首页 > 代码库 > jquery核心功能分析

jquery核心功能分析

作者:zccst

核心功能包括:

jQuery是如何定义的,如何调用的,如何扩展的。掌握核心方法是如何实现的,是理解jQuery源码的关键。这里理解了一切豁然开朗。

1,如何定义,即入口

// Define a local copy of jQuery
var jQuery = function( selector, context ) {
    // The jQuery object is actually just the init constructor ‘enhanced‘
    return new jQuery.fn.init( selector, context, rootjQuery );//jQuery对象仅仅是构造函数jQuery.prototype.init加强版
}

 

2,jQuery的原型,及与jQuery.fn.init的关系

//定义对象方法,也即只有通过$("xx").的方式才能调用。

jQuery.fn = jQuery.prototype = {

    init:function( selector, context, rootjQuery ) {

        return jQuery.makeArray( selector, this );

    }

    其他还有很多属性和方法,

    属性有:jquery,constructor, selector, length

    方法有:toArray,get, pushStack,each, ready,slice, first,last,eq, map,end, push, sort, splice

...

}

 

//把jQuery.prototype赋给jQuery.prototype.init.prototype,是为了后面的实例化

// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;

也即是,$("xx")拥有了实例方法,可以调用。(调用jQuery.prototype下定义的方法)

 

3,extend扩展对象方法和静态方法原理

jQuery.extend = jQuery.fn.extend = function() {

    var target = arguments[0] || {};

    return target;

}

使用extend就方便了,无非就是$.extend({});和$.fn.extend({});如果你能在看到fn时理解联想到是jQuery.prototype就好了。

再通过this作用域看一下:

$.extend ->this是$-> this.aa()

$.fn.extend->this是$.fn-> this.aa()

附extend实现细节:

使用场景:

1,扩展一些函数

只有一个参数。例如:$.extend({f1:function(){},f2:function(){},f3:function(){}})

2,合并多个对象到第一个对象

(1)浅copy,第一个参数是目标对象。例如

var a = {name:"hello"}

var b = {age:30}

$.extend(a,b);//a={name:"hello",age:30}

(2)深copy,第一个参数是TRUE,第二个参数是目标对象。例如

var a = {name:{job:"it"}};
var b = {name:{age: 30 }};
//$.extend(a,b);
$.extend(true,a,b);
console.log(a);

 1 jQuery.extend = jQuery.fn.extend = function() {
 2     var options, name, src, copy, copyIsArray, clone,
 3         target = arguments[0] || {},
 4         i = 1,
 5         length = arguments.length,
 6         deep = false;
 7 
 8     // 是不是深复制  Handle a deep copy situation
 9     if ( typeof target === "boolean" ) {
10         deep = target;
11         target = arguments[1] || {};
12         // skip the boolean and the target
13         i = 2;
14     }
15 
16     // 不是对象类型  Handle case when target is a string or something (possible in deep copy)
17     if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
18         target = {};
19     }
20 
21     // 扩展插件的情况  extend jQuery itself if only one argument is passed
22     if ( length === i ) {//$.extend({f1:function(){},f2:function(){},f3:function(){}})
23         target = this;//this是$,或是$.fn
24         --i;
25     }
26 
27     for ( ; i < length; i++ ) {//可能有多个对象扩展到第一个对象上
28         // Only deal with non-null/undefined values
29         if ( (options = arguments[ i ]) != null ) {//options是一个对象
30             // Extend the base object
31             for ( name in options ) {
32                 src = http://www.mamicode.com/target[ name ];  //src是target里已经存在的value(也可能不存在)
33                 copy = options[ name ];//copy是待合入的一个value
34 
35                 // 防止循环引用  Prevent never-ending loop
36                 if ( target === copy ) {//例如:var a={};$.extend(a,{name:a});//可能导致循环引用
37                     continue;
38                 }
39 
40                 // if是深复制else是浅复制  Recurse if we‘re merging plain objects or arrays
41                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
42                     if ( copyIsArray ) {
43                         copyIsArray = false;
44                         clone = src && jQuery.isArray(src) ? src : [];
45 
46                     } else {
47                         clone = src && jQuery.isPlainObject(src) ? src : {};
48                     }
49 
50                     // 亮了,直至剥离至最深一层非对象类型,而且是逐个。Never move original objects, clone them
51                     target[ name ] = jQuery.extend( deep, clone, copy );
52 
53                 // Don‘t bring in undefined values
54                 } else if ( copy !== undefined ) {
55                     target[ name ] = copy;//target[ name ] = options[ name ];
56                 }
57             }
58         }
59     }
60 
61     // Return the modified object
62     return target;
63 };