2,extend()插件扩展

2016-3-30    分类: jQuery深入解剖

/*extend()插件扩展*/
 jQuery.extend = jQuery.fn.extend = function() {
    var src, copyIsArray, copy, name, options, clone,
        target = arguments[0] || {}, //获取第一个参数赋值给target
        i = 1,
        length = arguments.length,
        deep = false;

        //第一个参数为布尔值时同时也是为true时: 执行这步时 i=2
        if (typeof target === "boolean") {
            deep = target; //将布尔值的结果 赋值给 deep变量
            target = arguments[1] || {}; //在将第二个参数重新赋值给target变量
            i = 2;
        }

        //如果第一个参数不是布尔值,继续往下看



        //如果第一个参数不是object类型并且也不是function类型时: 执行这步时 i=1
         if (typeof target !== "object" && !jQuery.isFunction(target)) { //执行以下代码
           target = {}; //那么就将点一个参数设置为空对象
         }



        //如果只有一个参数时,并且是对象或者函数类型: 执行这步时 i=0
         if (length === i) { //判断接受参数的数量
          target = this; //把jQuery对象赋值给target
          --i;
         }

        // 可以传入多个复制源
        // i 是从 1或2
        // 传入布尔值时(一般为true,不传时默认已经是false了) 还定义了目标对象 i=2
        for (; i < length; i++) {
          // Only deal with non-null/undefined values
          // 将每个源的属性全部复制到 target 上

           if ((options = arguments[i]) != null) {
              // Extend the base object
              for (name in options) {
              // src 是源(即本身)的值
              // copy 是即将要复制过去的值
                src = target[name];
                copy = options[name];

              // Prevent never-ending loop
               // 防止有环,例如 extend(true, target, {'target':target});
             if (target === copy) {
                continue;
             }

           // Recurse if we're merging plain objects or arrays
            // 这里是递归调用,最终都会到下面的 else if 分支
            // jQuery.isPlainObject 用于测试是否为纯粹的对象
            // 纯粹的对象指的是 通过 "{}" 或者 "new Object" 创建的
            // 如果是深复制
           if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
             // 数组
             if (copyIsArray) {
                copyIsArray = false;
                clone = src && jQuery.isArray(src) ? src : [];

                // 对象
              } else {
                clone = src && jQuery.isPlainObject(src) ? src : {};
              }

                  // Never move original objects, clone them
                 // 递归
                target[name] = jQuery.extend(deep, clone, copy);

              // Don't bring in undefined values
              // 最终都会到这条分支
             // 简单的值覆盖
             } else if (copy !== undefined) {
               target[name] = copy;
             }
           }
       }
   }

 // Return the modified object
 // 返回新的 target
 // 如果 i < length ,是直接返回没经过处理的 target,也就是 arguments[0]
 // 也就是如果不传需要覆盖的源,调用 $.extend 其实是增加 jQuery 的静态方法
   return target;
 }; //13

extend