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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值