jQuery 源码学习(一)jQuery.extend()

来源:互联网 发布:网络营销模拟软件 编辑:程序博客网 时间:2024/05/22 21:39

jQuery.extend()

用于将一个或多个对象 合并到目标对象中

- 参数:

  1. deep 值类型:boolean 是否深度遍历; 缺省值 :false;
  2. target 值类型:Object 目标对象(被扩展的对象);
  3. Object1…ObjectN 值类型:Obejct 扩展的对象;

- 实现:

1. 声明全局变量;

  - i 变量存储 扩展对象在参数中的开始位置;默认为1 即arguments[1]  - target 默认 arguments[0] 不存在则创建一个{}  - length 传入参数的个数,用于下面循环赋值时用;
/*  *target被扩展的对象  *length参数的数量  *deep是否深度操作  */  var options, name, src, copy, copyIsArray, clone,    target = arguments[0] || {},    i = 1,    length = arguments.length,    deep = false;

2. 判断传入的参数值

 - target 是否为boolean类型 ;是 :改变deep 默认值,i 顺延一位 为2 - 判断target 值 是否合法; - 判断length 长度 如果 没有传入扩展对象则把this 赋值给target **?? 不是很懂**
  // target为第一个参数,如果第一个参数是Boolean类型的值,则把target赋值给deep  // deep表示是否进行深层面的复制,当为true时,进行深度复制,否则只进行第一层扩展  // 然后把第二个参数赋值给target  if ( typeof target === "boolean" ) {    deep = target;    target = arguments[1] || {};    // 将i赋值为2,跳过前两个参数    i = 2;  }  // target既不是对象也不是函数则把target设置为空对象。  if ( typeof target !== "object" && !jQuery.isFunction(target) ) {    target = {};  }  // 如果只有一个参数,则把jQuery对象赋值给target,即扩展到jQuery对象上  if ( length === i ) {    target = this;    // i减1,指向被扩展对象    --i;  }

3. 判断传入的参数值

  • 循环遍历 arguments[i] 的属性,存到 copy 变量中;target 原有的属性存储到 src 中;
  • 判断 这个copy 是否是一个纯粹的对象通过($.isPlainObject()方法) 或者 是一个数组,且 deep 参数传入值为true;
  • 如果满足递归条件 再次调用 $.extend(); 传入 src 作为target copy 作为扩展对象;
  • 如果不满足条件 直接 赋值;
  • 完成循环 返回 对象;
 // 开始遍历需要被扩展到target上的参数  for ( ; i < length; i++ ) {    // 处理第i个被扩展的对象,即除去deep和target之外的对象    if ( (options = arguments[ i ]) != null ) {      // 遍历第i个对象的所有可遍历的属性      for ( name in options ) {        // 根据被扩展对象的键获得目标对象相应值,并赋值给src        src = target[ name ];        // 得到被扩展对象的值        copy = options[ name ];        // 这里为什么是比较target和copy?        if ( target === copy ) {          continue;        }        // 当用户想要深度操作时,递归合并        // copy是纯对象或者是数组        if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {          // 如果是数组          if ( copyIsArray ) {            // 将copyIsArray重新设置为false,为下次遍历做准备。            copyIsArray = false;            // 判断被扩展的对象中src是不是数组            clone = src && jQuery.isArray(src) ? src : [];          } else {             // 判断被扩展的对象中src是不是纯对象            clone = src && jQuery.isPlainObject(src) ? src : {};          }          // 递归调用extend方法,继续进行深度遍历          target[ name ] = jQuery.extend( deep, clone, copy );        // 如果不需要深度复制,则直接把copy(第i个被扩展对象中被遍历的那个键的值)        } else if ( copy !== undefined ) {          target[ name ] = copy;        }      }    }  }  // 原对象被改变,因此如果不想改变原对象,target可传入{}  return target;};

转载自:
http://www.cnblogs.com/charling/p/3452677.html