jQuery的深复制以及自己实现一个简单的

本文详细介绍了jQuery的深复制实现原理,并提供了一个自定义的深拷贝函数myCopy作为示例。深入理解深拷贝对于JavaScript对象操作至关重要,文章探讨了如何处理复杂对象和数组的复制,以及在实际开发中的应用。
摘要由CSDN通过智能技术生成

1. jQuery 的深复制
    function copy() {
      var options, // 被复制对象,主要是用于遍历其属性
          name,    // 属性名
          src,     // 复制到的对象
          copy,    // 被复制对象的属性
          copyIsArray,  // 被复制对象的该属性是一个数组类型
          clone,   // 克隆到的临时对象
        target = arguments[ 0 ] || {},	// target是第一个参数或者空对象
        i = 1,     // 指向对象
        length = arguments.length,  // 参数数量
        deep = false; // 

      // Handle a deep copy situation
      if ( typeof target === "boolean" ) {	// 第一个参数是boolean类型
        deep = target;	// 是否深度复制

        // Skip the boolean and the target
        target = arguments[ i ] || {};	// 此时i = 1,如果有第二个参数,target是第二个参数,否则为空对象
        i++;	// i = 2
      }
      // target指向需要拷贝到的对象,i指向需要被拷贝的第一个对象
	    // Handle case= when target is a string or something (possible in deep copy)
      // target 是string或者其他(可能是深拷贝的对象)
      // target 不是object类型也不是function类型
      // 即target不是引用类型,target是一个值类型
      // 那么target是一个空对象
      if ( typeof target !== "object" && !isFunction( target ) ) {
        target = {};
      }

      // Extend jQuery itself if only one argument is passed
      // 如果只有一个参数那么,默认是jQuery被拓展的对象
      // 此时,i = 2,或者 i = 1
      // target 指向需要拷贝到的对象
      // i 指向下一个需要拷贝到的对象的下一个参数
      // $.extend(boolean, obj1 [,obj2])
      // i === length 说明已无后续参数,所以结果就是this
      // target指向需要拷贝到的对象,i指向第一个需要被拷贝的对象
      // 如果 i === length 这说明 i 指向的位置不存在
      // 那么此时只有两个参数,boolean,target
      // 或者只有一个参数target
      // 那么就将该参数复制到对象上
      if ( i === length ) {
        target = this;
        i--;
        // i 指向需要被拷贝的对象
      }
      for ( ; i < length; i++ ) {
        // Only deal with non-null/undefined values
        // 仅处理非空/尚未赋值的对象
        if ( ( options = arguments[ i ] ) != null ) {
          // Extend the base object
          // 拓展基本对象
          for ( name in options ) {
            // 对于options的每一个属性,name是属性名
            copy = options[ name ];
            // Prevent Object.prototype pollution
            // 阻止Object.prototype污染
            // Prevent never-ending loop
            // 阻止永不结束的循环,只能检测一层嵌套
            if ( name === "__proto__" || target === copy ) {
              continue;
            }
            // Recurse if we're merging plain objects or arrays
            // 如果是纯粹的对象或者数组则需要合并
            // copy 不为空
            // deep 深拷贝
            // 是纯粹的object或者是数组
            if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
              ( copyIsArray = Array.isArray( copy ) ) ) ) {
              src = target[ name ];
              // Ensure proper type for the source value
              // copyIsArray:copy对象中的这一项是数组
              // src:target对象中的这一项不是数组
              // 那么让clone是一个数组
              if ( copyIsArray && !Array.isArray( src ) ) {
                clone = [];
              } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
                // copy对象中的这一项不是是数组
                // src中的这一项不是纯粹的对象
                clone = {};
              } else {
                clone = src;
              }
              copyIsArray = false;
              // 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
    // 返回修改后的对象
	return target;
};

$.extend( [deep ], target, object1 [, objectN ] )
(来自:菜鸟教程)

是否深复制、目标对象、被复制的对象

2. 仿写一个自己的

jQuery的extend方法,支持多个对象,这里实现一个简单的。

  function myCopy() {
      var target,               // 结果
       copy,                    // 属性值
       source = arguments[0];   // 需要复制的对象
      if (!source) {
        return source;
      }
      if ( ( typeof source === "object" ) ) {
        target = new A.constructor();     // 保证结果的 原型和构造函数 与原对象一致
        for ( name in source) {
          if (!A.hasOwnProperty(name)) {  // 属性不在原型上,说明在原型链上,那就跳过
            continue;
          }
          copy = source[name];            // copy:需要拷贝的属性的值,name:需要拷贝的属性的属性名
          target[ name ] = myCopy( copy );// 复制copy
        }
      }
      else {
        // 包括值类型和函数
        target = source;
      }
      return target;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值