`
nuysoft
  • 浏览: 520475 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
91bd5d30-bd1e-3b00-9210-87db1cca0016
jQuery技术内幕
浏览量:200461
社区版块
存档分类
最新评论

[原创] jQuery源码分析-03构造jQuery对象-工具函数

阅读更多

作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com

声明:本文为原创文章,如需转载,请注明来源并保留原文链接。

 

 

读读写写,不对的地方请告诉我,多多交流共同进步,本章的的PDF等本章写完了发布。

 

jQuery源码分析系列的目录请查看 http://nuysoft.iteye.com/blog/1177451想系统的好好写写,目前还是从我感兴趣的部分开始,如果大家有对哪个模块感兴趣的,建议优先分析的,可以告诉我,一起学习。

 

3.4        其他静态工具函数

// 扩展工具函数

jQuery.extend({

    // http://www.w3school.com.cn/jquery/core_noconflict.asp

    // 释放$ jQuery 控制权

    // 许多 JavaScript 库使用 $ 作为函数或变量名,jQuery 也一样。

    // jQuery 中,$ 仅仅是 jQuery 的别名,因此即使不使用 $ 也能保证所有功能性。

    // 假如我们需要使用 jQuery 之外的另一 JavaScript 库,我们可以通过调用 $.noConflict() 向该库返回控制权。

   

    // 通过向该方法传递参数 true,我们可以将 $ jQuery 的控制权都交还给另一JavaScript库。

    noConflict: function( deep ) {

       // 交出$的控制权

       if ( window.$ === jQuery ) {

           window.$ = _$;

       }

       // 交出jQuery的控制权

       if ( deep && window.jQuery === jQuery ) {

           window.jQuery = _jQuery;

       }

   

       return jQuery;

    },

   

    // Is the DOM ready to be used? Set to true once it occurs.

    isReady: false,

   

    // A counter to track how many items to wait for before

    // the ready event fires. See #6781

    // 一个计数器,用于跟踪在ready事件出发前的等待次数

    readyWait: 1,

   

    // Hold (or release) the ready event

    // 继续等待或触发

    holdReady: function( hold ) {

       if ( hold ) {

           jQuery.readyWait++;

       } else {

           jQuery.ready( true );

       }

    },

   

    // Handle when the DOM is ready

    // 文档加载完毕句柄

    // http://www.cnblogs.com/fjzhou/archive/2011/05/31/jquery-source-4.html

    ready: function( wait ) {

       // Either a released hold or an DOMready/load event and not yet ready

       //

       if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {

           // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).

           // 确保document.body存在

           if ( !document.body ) {

              return setTimeout( jQuery.ready, 1 );

           }

   

           // Remember that the DOM is ready

           jQuery.isReady = true;

   

           // If a normal DOM Ready event fired, decrement, and wait if need be

           if ( wait !== true && --jQuery.readyWait > 0 ) {

              return;

           }

   

           // If there are functions bound, to execute

           readyList.resolveWith( document, [ jQuery ] );

   

           // Trigger any bound ready events

           if ( jQuery.fn.trigger ) {

              jQuery( document ).trigger( "ready" ).unbind( "ready" );

           }

       }

    },

   

    // 初始化readyList事件处理函数队列

    // 兼容不同浏览对绑定事件的区别

    bindReady: function() {

       if ( readyList ) {

           return;

       }

   

       readyList = jQuery._Deferred();

   

       // Catch cases where $(document).ready() is called after the

       // browser event has already occurred.

       if ( document.readyState === "complete" ) {

           // Handle it asynchronously to allow scripts the opportunity to delay ready

           return setTimeout( jQuery.ready, 1 );

       }

   

       // Mozilla, Opera and webkit nightlies currently support this event

       // 兼容事件,通过检测浏览器的功能特性,而非嗅探浏览器

       if ( document.addEventListener ) {

           // Use the handy event callback

           // 使用较快的加载完毕事件

           document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

   

           // A fallback to window.onload, that will always work

           // 注册window.onload回调函数

           window.addEventListener( "load", jQuery.ready, false );

   

       // If IE event model is used

       } else if ( document.attachEvent ) {

           // ensure firing before onload,

           // maybe late but safe also for iframes

           // 确保在onload之前触发onreadystatechange,可能慢一些但是对iframes更安全

           document.attachEvent( "onreadystatechange", DOMContentLoaded );

   

           // A fallback to window.onload, that will always work

           // 注册window.onload回调函数

           window.attachEvent( "onload", jQuery.ready );

   

           // If IE and not a frame

           // continually check to see if the document is ready

           var toplevel = false;

   

           try {

              toplevel = window.frameElement == null;

           } catch(e) {}

   

           if ( document.documentElement.doScroll && toplevel ) {

              doScrollCheck();

           }

       }

    },

   

    // See test/unit/core.js for details concerning isFunction.

    // Since version 1.3, DOM methods and functions like alert

    // aren't supported. They return false on IE (#2968).

    // 是否函数

    isFunction: function( obj ) {

       return jQuery.type(obj) === "function";

    },

   

    // 是否数组

    // 如果浏览器有内置的 Array.isArray 实现,就使用浏览器自身的实现方式,

    // 否则将对象转为String,看是否为"[object Array]"

    isArray: Array.isArray || function( obj ) {

       return jQuery.type(obj) === "array";

    },

   

    // A crude way of determining if an object is a window

    // 简单的判断(判断setInterval属性)是否window对象

    isWindow: function( obj ) {

       return obj && typeof obj === "object" && "setInterval" in obj;

    },

   

    // 是否是保留字NaN

    isNaN: function( obj ) {

       // 等于null 不是数字 或调用window.isNaN判断

       return obj == null || !rdigit.test( obj ) || isNaN( obj );

    },

    // 获取对象的类型

    type: function( obj ) {

       // 通过核心API创建一个对象,不需要new关键字

       // 普通函数不行

       // 调用Object.prototype.toString方法,生成 "[object Xxx]"格式的字符串

       // class2type[ "[object " + name + "]" ] = name.toLowerCase();

       return obj == null ?

           String( obj ) :

           class2type[ toString.call(obj) ] || "object";

    },

   

    // 检查obj是否是一个纯粹的对象(通过"{}" "new Object"创建的对象)

    // console.info( $.isPlainObject( {} ) ); // true

    // console.info( $.isPlainObject( '' ) ); // false

    // console.info( $.isPlainObject( document.location ) ); // true

    // console.info( $.isPlainObject( document ) ); // false

    // console.info( $.isPlainObject( new Date() ) ); // false

    // console.info( $.isPlainObject( ) ); // false

   

    // isPlainObject分析与重构 http://www.jb51.net/article/25047.htm

    // jQuery.isPlainObject()的理解 http://www.cnblogs.com/phpmix/articles/1733599.html

    isPlainObject: function( obj ) {

       // Must be an Object.

       // Because of IE, we also have to check the presence of the constructor property.

       // Make sure that DOM nodes and window objects don't pass through, as well

       // 必须是一个对象

       // 因为在IE8中会抛出非法指针异常,必须检查constructor属性

       // DOM节点和window对象,返回false

      

       // obj不存在 object类型 DOM节点 widnow对象,直接返回false

       // 测试以下三中可能的情况:

       // jQuery.type(obj) !== "object" 类型不是object,忽略

       // obj.nodeType 认为DOM节点不是纯对象

       // jQuery.isWindow( obj ) 认为window不是纯对象

       if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {

           return false;

       }

   

       // Not own constructor property must be Object

       // 测试constructor属性

       // 具有构造函数constructor,却不是自身的属性(即通过prototype继承的),

       if ( obj.constructor &&

           !hasOwn.call(obj, "constructor") &&

           !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {

           return false;

       }

   

       // Own properties are enumerated firstly, so to speed up,

       // if last one is own, then all properties are own.

   

       var key;

       for ( key in obj ) {}

       // key === undefined及不存在任何属性,认为是简单的纯对象

       // hasOwn.call( obj, key ) 属性key不为空,且属性key的对象自身的(即不是通过prototype继承的)

       return key === undefined || hasOwn.call( obj, key );

    },

    // 是否空对象

    isEmptyObject: function( obj ) {

       for ( var name in obj ) {

           return false;

       }

       return true;

    },

    // 抛出一个异常

    error: function( msg ) {

       throw msg;

    },

    // 解析JSON

    // parseJSON把一个字符串变成JSON对象。

    // 我们一般使用的是evalparseJSON封装了这个操作,但是eval被当作了最后手段。

    // 因为最新JavaScript标准中加入了JSON序列化和反序列化的API

    // 如果浏览器支持这个标准,则这两个API是在JS引擎中用Native Code实现的,效率肯定比eval高很多。

    // 目前来看,ChromeFirefox4都支持这个API

    parseJSON: function( data ) {

       if ( typeof data !== "string" || !data ) {

           return null;

       }

   

       // Make sure leading/trailing whitespace is removed (IE can't handle it)

       data = jQuery.trim( data );

   

       // Attempt to parse using the native JSON parser first

       // 原生JSON API。反序列化是JSON.stringify(object)

       if ( window.JSON && window.JSON.parse ) {

           return window.JSON.parse( data );

       }

   

       // Make sure the incoming data is actual JSON

       // Logic borrowed from http://json.org/json2.js

       // ... 大致地检查一下字符串合法性

       if ( rvalidchars.test( data.replace( rvalidescape, "@" )

           .replace( rvalidtokens, "]" )

           .replace( rvalidbraces, "")) ) {

   

           return (new Function( "return " + data ))();

   

       }

       jQuery.error( "Invalid JSON: " + data );

    },

   

    // Cross-browser xml parsing

    // (xml & tmp used internally)

    // 解析XML 跨浏览器

    // parseXML函数也主要是标准APIIE的封装。

    // 标准APIDOMParser对象。

    // IE使用的是Microsoft.XMLDOM ActiveXObject对象。

    parseXML: function( data , xml , tmp ) {

   

       if ( window.DOMParser ) { // Standard 标准XML解析器

           tmp = new DOMParser();

           xml = tmp.parseFromString( data , "text/xml" );

       } else { // IE IEXML解析器

           xml = new ActiveXObject( "Microsoft.XMLDOM" );

           xml.async = "false";

           xml.loadXML( data );

       }

   

       tmp = xml.documentElement;

   

       if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {

           jQuery.error( "Invalid XML: " + data );

       }

   

       return xml;

    },

    // 无操作函数

    noop: function() {},

   

    // Evaluates a script in a global context

    // Workarounds based on findings by Jim Driscoll

    // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context

    // globalEval函数把一段脚本加载到全局contextwindow)中。

    // IE中可以使用window.execScript

    // 其他浏览器 需要使用eval

    // 因为整个jQuery代码都是一整个匿名函数,所以当前contextjQuery,如果要将上下文设置为window则需使用globalEval

    globalEval: function( data ) {

       // data非空

       if ( data && rnotwhite.test( data ) ) {

           // We use execScript on Internet Explorer

           // We use an anonymous function so that context is window

           // rather than jQuery in Firefox

           ( window.execScript || function( data ) {

              window[ "eval" ].call( window, data );

           } )( data );

       }

    },

    // 判断节点名称是否相同

    nodeName: function( elem, name ) {

       // 忽略大小写

       return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();

    },

   

    // args is for internal usage only

    // 遍历对象或数组

    each: function( object, callback, args ) {

       var name, i = 0,

           length = object.length,

           isObj = length === undefined || jQuery.isFunction( object );

       // 如果有参数args,调用apply,上下文设置为当前遍历到的对象,参数使用args

       if ( args ) {

           if ( isObj ) {

              for ( name in object ) {

                  if ( callback.apply( object[ name ], args ) === false ) {

                     break;

                  }

              }

           } else {

              for ( ; i < length; ) {

                  if ( callback.apply( object[ i++ ], args ) === false ) {

                     break;

                  }

              }

           }

   

       // A special, fast, case for the most common use of each

       // 没有参数args则调用,则调用call,上下文设置为当前遍历到的对象,参数设置为key/indexvalue

       } else {

           if ( isObj ) {

              for ( name in object ) {

                  if ( callback.call( object[ name ], name, object[ name ] ) === false ) {

                     break;

                  }

              }

           } else {

              for ( ; i < length; ) {

                  if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {

                     break;

                  }

              }

           }

       }

   

       return object;

    },

   

    // Use native String.trim function wherever possible

    // 尽可能的使用本地String.trim方法,否则先过滤开头的空格,再过滤结尾的空格

    trim: trim ?

       function( text ) {

           return text == null ?

              "" :

              trim.call( text );

       } :

   

       // Otherwise use our own trimming functionality

       function( text ) {

           return text == null ?

              "" :

              text.toString().replace( trimLeft, "" ).replace( trimRight, "" );

       },

   

    // results is for internal usage only

    // 将伪数组转换为数组

    makeArray: function( array, results ) {

       var ret = results || [];

   

       if ( array != null ) {

           // The window, strings (and functions) also have 'length'

           // The extra typeof function check is to prevent crashes

           // in Safari 2 (See: #3039)

           // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930

           // 一大堆浏览器兼容性测试,真实蛋疼

           var type = jQuery.type( array );

           // 测试:有没有length属性、字符串、函数、正则

           // 不是数组,连伪数组都不是

           if ( array.length == null

                  || type === "string"

                  || type === "function"

                  || type === "regexp"

                  || jQuery.isWindow( array ) ) {

              push.call( ret, array );

           } else {

              // $.type( $('div') ) // object

              jQuery.merge( ret, array );

           }

       }

   

       return ret;

    },

    //

    inArray: function( elem, array ) {

       // 是否有本地化的Array.prototype.indexOf

       if ( indexOf ) {

           // 直接调用Array.prototype.indexOf

           return indexOf.call( array, elem );

       }

       // 遍历数组,查找是否有完全相等的元素,并返回下标

       // 循环的小技巧:把array.length存放到length变量中,可以减少一次作用域查找

       for ( var i = 0, length = array.length; i < length; i++ ) {

           if ( array[ i ] === elem ) {

              return i;

           }

       }

       // 如果返回-1,则表示不在数组中

       return -1;

    },

    // 将数组second合并到数组first

    merge: function( first, second ) {

       var i = first.length, //

           j = 0;

      

       // 如果secondlength属性是Number类型,则把second当数组处理

       if ( typeof second.length === "number" ) {

           for ( var l = second.length; j < l; j++ ) {

              first[ i++ ] = second[ j ];

           }

   

       } else {

           // 遍历second,将非undefined的值添加到first

           while ( second[j] !== undefined ) {

              first[ i++ ] = second[ j++ ];

           }

       }

       // 修正firstlength属性,因为first可能不是真正的数组

        first.length = i;

   

       return first;

    },

    // 过滤数组,返回新数组;callback返回true时保留;如果invtruecallback返回false才会保留

    grep: function( elems, callback, inv ) {

       var ret = [], retVal;

       inv = !!inv;

   

       // Go through the array, only saving the items

       // that pass the validator function

       // 遍历数组,只保留通过验证函数callback的元素

       for ( var i = 0, length = elems.length; i < length; i++ ) {

           // 这里callback的参数列表为:value, index,与each的习惯一致

           retVal = !!callback( elems[ i ], i );

           // 是否反向选择

           if ( inv !== retVal ) {

              ret.push( elems[ i ] );

           }

       }

   

       return ret;

    },

   

    // arg is for internal usage only

    // 将数组或对象elems的元素/属性,转化成新的数组

    map: function( elems, callback, arg ) {

       var value, key, ret = [],

           i = 0,

           length = elems.length,

           // jquery objects are treated as arrays

           // 检测elems是否是(伪)数组

           // 1. jQuery对象也当成数组处理

           // 2. 检测length属性是否存在,length等于0,或第一个和最后一个元素是否存在,或jQuery.isArray返回true

           isArray = elems instanceof jQuery

              || length !== undefined && typeof length === "number"

                  && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;

      

       // 是数组或对象的差别,仅仅是遍历的方式不同,没有其他的区别

      

       // Go through the array, translating each of the items to their

       // 遍历数组,对每一个元素调用callback,将返回值不为null的值,存入ret

       if ( isArray ) {

           for ( ; i < length; i++ ) {

              // 执行callback,参数依次为value, index, arg

              value = callback( elems[ i ], i, arg );

              // 如果返回null,则忽略(无返回值的function会返回undefined

              if ( value != null ) {

                  ret[ ret.length ] = value;

              }

           }

   

       // Go through every key on the object,

       // 遍历对象,对每一个属性调用callback,将返回值不为null的值,存入ret

       } else {

           for ( key in elems ) {

              // 执行callback,参数依次为value, key, arg

              value = callback( elems[ key ], key, arg );

              // 同上

              if ( value != null ) {

                  ret[ ret.length ] = value;

              }

           }

       }

   

       // Flatten any nested arrays

       // 使嵌套数组变平

       // concat

       // 如果某一项为数组,那么添加其内容到末尾。

       // 如果该项目不是数组,就将其作为单个的数组元素添加到数组的末尾。

       return ret.concat.apply( [], ret );

    },

   

    // A global GUID counter for objects

    guid: 1,

   

    // Bind a function to a context, optionally partially applying any

    // arguments.

    // 代理方法:为fn指定上下文(即this

    // jQuery.proxy( function, context )

    // jQuery.proxy( context, name )

    proxy: function( fn, context ) {

       // 如果context是字符串,设置上下文为fnfnfn[ context ]

       // 即设置fncontext方法的上下文为fn(默认不是这样吗???TODO

       if ( typeof context === "string" ) {

           var tmp = fn[ context ];

           context = fn;

           fn = tmp;

       }

   

       // Quick check to determine if target is callable, in the spec

       // this throws a TypeError, but we will just return undefined.

       // 快速测试fn是否是可调用的(即函数),在文档说明中,会抛出一个TypeError

       // 但是这里仅返回undefined

       if ( !jQuery.isFunction( fn ) ) {

           return undefined;

       }

   

       // Simulated bind

       var args = slice.call( arguments, 2 ), // 从参数列表中去掉fn,context

           proxy = function() {

              // 设置上下文为context和参数

              return fn.apply( context, args.concat( slice.call( arguments ) ) );

           };

   

       // Set the guid of unique handler to the same of original handler, so it can be removed

       // 统一guid,使得proxy能够被移除

       proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;

   

       return proxy;

    },

   

    // Mutifunctional method to get and set values to a collection

    // The value/s can be optionally by executed if its a function

    // 多功能函数,读取或设置集合的属性值;值为函数时会被执行

    // fnjQuery.fn.css, jQuery.fn.attr, jQuery.fn.prop

    access: function( elems, key, value, exec, fn, pass ) {

       var length = elems.length;

   

       // Setting many attributes

       // 如果有多个属性,则迭代

       if ( typeof key === "object" ) {

           for ( var k in key ) {

              jQuery.access( elems, k, key[k], exec, fn, value );

           }

           return elems;

       }

   

       // Setting one attribute

       // 只设置一个属性

       if ( value !== undefined ) {

           // Optionally, function values get executed if exec is true

           exec = !pass && exec && jQuery.isFunction(value);

   

           for ( var i = 0; i < length; i++ ) {

              fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );

           }

   

           return elems;

       }

   

       // Getting an attribute

       // 读取属性

       return length ? fn( elems[0], key ) : undefined;

    },

    // 获取当前时间的便捷函数

    now: function() {

       return (new Date()).getTime();

    },

   

    // Use of jQuery.browser is frowned upon.

    // More details: http://docs.jquery.com/Utilities/jQuery.browser

    // 不赞成使用jQuery.browser,推荐使用jQuery.support

    // Navigator 正在使用的浏览器的信息

    // Navigator.userAgent 一个只读的字符串,声明了浏览器用于HTPP请求的用户代理头的值

    uaMatch: function( ua ) {

       ua = ua.toLowerCase();

       // 依次匹配各浏览器

       var match = rwebkit.exec( ua ) ||

           ropera.exec( ua ) ||

           rmsie.exec( ua ) ||

           ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||

           [];

       // match[1] || ""

       // match[1]false(空字符串、nullundefined0等)时,默认为""

       // match[2] || "0"

       // match[2]false(空字符串、nullundefined0等)时,默认为"0"

       return { browser: match[1] || "", version: match[2] || "0" };

    },

    // 创建一个新的jQuery副本,副本的属性和方法可以被改变,但是不会影响原始的jQuery对象

    // 有两种用法:

    // 1. 覆盖jQuery的方法,而不破坏原始的方法

    // 2.封装,避免命名空间冲突,可以用来开发jQuery插件

    // 值得注意的是,jQuery.sub()函数并不提供真正的隔离,所有的属性、方法依然指向原始的jQuery

    // 如果使用这个方法来开发插件,建议优先考虑jQuery UI widget工程

    sub: function() {

       function jQuerySub( selector, context ) {

           return new jQuerySub.fn.init( selector, context );

       }

       jQuery.extend( true, jQuerySub, this ); // 深度拷贝,将jQuery的所有属性和方法拷贝到jQuerySub

       jQuerySub.superclass = this;

       jQuerySub.fn = jQuerySub.prototype = this(); //

       jQuerySub.fn.constructor = jQuerySub;

       jQuerySub.sub = this.sub;

       jQuerySub.fn.init = function init( selector, context ) {

           if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {

              context = jQuerySub( context );

           }

   

           return jQuery.fn.init.call( this, selector, context, rootjQuerySub );

       };

       jQuerySub.fn.init.prototype = jQuerySub.fn;

       var rootjQuerySub = jQuerySub(document);

       return jQuerySub;

    },

    // 浏览器类型和版本:

    // $.browser.msie/mozilla/webkit/opera

    // $.browser.version

    // 不推荐嗅探浏览器类型jQuery.browser,而是检查浏览器的功能特性jQuery.support

    // 未来jQuery.browser可能会移到一个插件中

    browser: {}

});

9
0
分享到:
评论
10 楼 psl19892010 2012-12-06  
哎,完全看不懂!
9 楼 无赖君子 2012-09-28  
楼主偷懒了,很多都没有说明白,表示对jQuery.ready 这一块没看明白...
8 楼 tgwiloveyou 2012-09-04  
caniggia1986 写道
//merge方法我觉得可以简化
merge:function( first, second ) {
       var j = 0; 
       while ( second[j]) {
         first[first.length] = second[ j++ ];
       }  
       return first;
    };
//PS:Array.concat();不就可以完成数组的合并吗

是啊,不明白为什么需要typeof second.length === "number"这个判断,难道typeof second.length === "number"有可能不成立么?
7 楼 nuysoft 2012-08-20  
atoooo 写道
楼主,写的好高深,很懂看的不是很懂,有么有推荐的Javascript 好JQuery的书什么的看看啊?

无他,但手熟耳
6 楼 atoooo 2012-08-19  
楼主,写的好高深,很懂看的不是很懂,有么有推荐的Javascript 好JQuery的书什么的看看啊?
5 楼 王向众 2012-03-30  
jquery里面好多技巧啊,我想在基础知识掌握的差不多之后,自己的编程水平就体现在这些技巧上了吧。有的技巧可以代替好多行代码吧,有的技巧还能达到一些难以想到的效果。。。
4 楼 nuysoft 2011-12-14  
caniggia1986 写道
grep时的inv=!!inv;不错的用法,这样即使不传inv参数默认为false

很实用的技巧
3 楼 caniggia1986 2011-12-14  
grep时的inv=!!inv;不错的用法,这样即使不传inv参数默认为false
2 楼 caniggia1986 2011-12-14  
不对Array.concat()只能是数组间合并,first可能是jQuery类型的伪数组
1 楼 caniggia1986 2011-12-14  
//merge方法我觉得可以简化
merge:function( first, second ) {
       var j = 0; 
       while ( second[j]) {
         first[first.length] = second[ j++ ];
       }  
       return first;
    };
//PS:Array.concat();不就可以完成数组的合并吗

相关推荐

    jQuery源码分析-03构造jQuery对象

    ### jQuery源码分析—构造jQuery对象 #### 一、源码结构概览 根据所提供的文件内容,本节将深入分析如何构建jQuery对象及其核心构造逻辑。首先,让我们从整体上理解jQuery构造函数的设计思路。 ##### 总体结构 ...

    jQuery源码分析-03构造jQuery对象-源码结构和核心函数

    在进行jQuery源码分析的过程中,我们了解到jQuery对象是通过内部函数`jQuery.fn.init`构造的,其方法和属性则通过原型链继承自`jQuery.fn`,这是jQuery能够提供丰富且灵活DOM操作方法的基石。通过这种方式,即使不...

    jQuery源码分析-02正则表达式

    ### jQuery源码分析-02正则表达式 #### 正则表达式基础与应用 正则表达式是一种用于描述字符模式的强大工具,在多种编程语言中都有应用,其中包括JavaScript。在jQuery这样的JavaScript库中,正则表达式被广泛应用...

    139.jQuery源码分析-魔术方法.rar

    《jQuery源码分析——魔术方法》 jQuery,作为一款广泛使用的JavaScript库,以其简洁的API和强大的功能赢得了开发者们的喜爱。在深入理解jQuery的工作原理时,我们常常会遇到一些“魔术方法”,这些方法在特定场景...

    Jquery源码分析 源码

    《jQuery源码分析》 jQuery,作为一款广泛使用的JavaScript库,极大地简化了DOM操作、事件处理、动画制作以及Ajax交互。深入理解其源码对于提升JavaScript编程技能和优化前端性能至关重要。本文将从核心概念、设计...

    jQuery源码分析系列.pdf

    ### jQuery源码分析系列知识点概览 #### 一、总体架构与核心概念 - **前言开光**:介绍分析jQuery源码的目的和价值,强调通过深入研究源码,可以学习到先进的设计理念和实践技巧。 - **总体架构**:解析jQuery的...

    jQuery源码分析

    jQuery源码分析 00 前言开光 01 总体架构 03 构造jQuery对象-源码...03 构造jQuery对象-工具函数 05 异步队列 Deferred 08 队列 Queue 09 属性操作 10 事件处理-Event-概述和基础知识 15 AJAX-前置过滤器和请求分发器

    jQuery源码分析(1.7)

    ### jQuery源码分析关键知识点详解 #### 一、前言 在深入了解jQuery源码之前,有必要先简要介绍一下jQuery的基本情况及其对JavaScript编程领域的重要意义。jQuery作为一个轻量级、功能丰富的JavaScript库,在Web...

    JQuery源码详细中文注释_Jquery源码分析_

    总结,jQuery源码分析涉及的内容广泛,包括选择器引擎、事件处理、DOM操作、动画效果、Ajax通信以及插件开发等多个方面。深入理解jQuery源码,有助于我们更好地利用它来构建高效、易维护的Web应用。通过阅读中文注释...

    jquery 源码分析

    ### jQuery源码分析 #### 一、概述 jQuery作为一个卓越的JavaScript库,以其简洁高效的特性在前端开发领域占据了一席之地。与Prototype、YUI、Mootools等其他JavaScript库相比,jQuery更加注重实用性,去除了一些...

    jQuery源码分析-01总体架构分析

    《jQuery源码分析-总体架构解析》 在深入探究jQuery的源码之前,我们首先要理解其总体架构的设计理念。jQuery以其高效、易用的特性深受开发者喜爱,而这背后离不开其精心设计的架构。本文将围绕jQuery的核心构造...

    jQuery源码分析系列

    jQuery源码分析系列涉及了对jQuery库内部实现的详细解读,jQuery作为前端开发中最常用的JavaScript库之一,它简化了DOM操作、事件处理、动画效果和AJAX交互等操作。通过深入分析jQuery的源码,开发者可以学习到先进...

    JavaScript和jQuery实战手册源码--the missing manual

    7. **面向对象编程**:介绍如何用jQuery实现面向对象的设计模式,如构造函数和原型链。 8. **错误处理和调试**:通过`.error()`, `console.log()`等来处理错误和调试代码。 9. **性能优化**:示例可能包括如何减少...

    login_jquery和jq-UI源码_

    二、jQuery源码解析 jQuery的核心在于它的构造函数`$()`,它接受一个参数,可以是CSS选择器、HTML字符串或者DOM元素。源码中,`init`函数负责初始化,它首先解析参数,然后对选择到的元素进行操作。例如,`$...

    JQuery源码的奥秘逐行分析视频教程

    ### JQuery源码的奥秘逐行分析视频教程 #### JQuery简介 JQuery 是一款轻量级的 JavaScript 库,它极大地简化了 HTML 文档遍历、事件处理、动画以及 Ajax 交互等操作。JQuery 提供了一个简洁且强大的 API 接口,...

Global site tag (gtag.js) - Google Analytics