jQuery源码分析之extend方法

标签: JavaScript jQuery

解析jQueryextend方法之实现

 1 /*
 2 * 实现将源对象(source)复制到目标对象(target)
 3 * 复制有深拷贝和浅拷贝(deep)
 4 * this表示调用extend方法的对象,即方法的调用对象本身
 5 * 以下为调用extend传入不同参数所表示的含义
 6 * (1)extend(obj)-->deep=false;target=this;source=arguments[0];
 7 * (2)extend(boolean,obj)-->deep=arguments[0];target=this;source=arguments[1];
 8 * (3)extend(obj1,...objn)-->deep=false;target=arguments[0];source=[arguments[1],...arguments[n-1]](n>=2);
 9 * (4)extend(boolean,obj1,obj2......)-->deep=arguments[0],target=arguments[1];source=[arguments[2],...arguments[n-1]](n>=3);
10 */
11 jQuery.extend = jQuery.fn.extend = function() {
12    var   options, name, src, copy, copyIsArray, clone,
13          target = arguments[0] || {},
14          i = 1,
15          length = arguments.length,
16          deep = false;
17       // Handle a deep copy situation
18       //第一个参数是boolean类型则标识是否执行深拷贝
19          if ( typeof target === "boolean" ) {
20              deep = target;
21              target = arguments[1] || {};
22              // skip the boolean and the target
23              i = 2;
24          }
25       // Handle case when target is a string or something (possible in deep copy)
26       // 目标对象类型必须是对象(包含数组)或函数(函数也是对象,可以有属性和方法)
27       // 如果不是则将目标对象重置为空对象
28          if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
29              target = {};
30          }
31       // extend jQuery itself if only one argument is passed
32       // 目标对象为调用对象本身,只有(1)/(2)两种情况
33          if ( length === i ) {
34              target = this;
35              --i;
36          }
37          for ( ; i < length; i++ ) {
38           // Only deal with non-null/undefined values
39          // 非null/undefined值才处理
40              if ( (options = arguments[ i ]) != null ) {
41              // Extend the base object
42                  for ( name in options ) {
43                      src = target[ name ];
44                      copy = options[ name ];
45                 // Prevent never-ending loop
46                      // 若目标对象为源对象本身,则跳过循环
47                      if ( target === copy ) {
48                          continue;
49                      }
50                  // Recurse if we're merging plain objects or arrays
51                      if ( deep && copy && ( jQuery.isPlainObject(copy) 
52                                || (copyIsArray = jQuery.isArray(copy)) ) ) {
53                          // 深拷贝。当源对象为普通对象(普通对象即Object实例)或数组对象时。
54                          if ( copyIsArray ) {
55                             copyIsArray = false;
56                       //源对象为数组,目标对象非数组,则目标对象重置为空数组
57                             clone = src && jQuery.isArray(src) ? src : [];
58                          } else {
59                        //源对象为普通对象,目标对象非普通对象,则目标对象重置为空对象
60                              clone = src && jQuery.isPlainObject(src) ? src : {};
61                          }
62                     // Never move original objects, clone them
63                          // 递归调用extend,进行深拷贝
64                          target[ name ] = jQuery.extend( deep, clone, copy );
65                      } 
66                 // Don't bring in undefined values
67                 // 源对象为undefined则不拷贝
68                      else if ( copy !== undefined ) {
69                    // 浅拷贝
70                          target[ name ] = copy;
71                      }
72                  }
73          }
74      }
75    // Return the modified object
76  return target;
77 };
留言板
comments powered by Disqus