深拷贝的实现方式

1,通过JSON对象实现深拷贝;缺点: 无法实现对对象中方法的深拷贝,会显示为undefined

      newValue = JSON.parse(JSON.stringify(oldValue))

2,通过JQuery的extend方法实现

var array = [1, 2, 3, 4]
var newArray = $.extend(true, [], array)  // true为深拷贝,false为浅拷贝
  • 3使用递归

    function deepClone(obj) {
      // 判断拷贝的是对象还是数组
      var objClone = Array.isArray(obj) ? [] : {}
      // 进行深拷贝的对象不能为空
      if(obj && typeof obj === 'object') {
        for(let key in obj) {
          if(obj.hasOwnProperty(key)) {
            if(obj[key] && typeof obj[key] === 'object') {
              objClone[key] = deepClone(obj[key])
            } else {
              objClone[key] = obj[key]
            }
          }
        }
      }
      return objClone
    }

         

  • 如果对象的value是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象;当对象只有一级属性,没有二级属性的时候,此方法也为深拷贝,但当对象中包含对象时,在二级属性以后仍然是浅拷贝

  • lodash函数库实现深拷贝, lodash.cloneDeep()

  • Reflect方法

  • function deepClone(obj) { if (!isObject(obj)) { throw new Error('obj 不是一个对象!') } let isArray = Array.isArray(obj) let cloneObj = isArray ? [...obj] : { ...obj } Reflect.ownKeys(cloneObj).forEach(key => { cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key] }) return cloneObj }

  • 用slice实现对数组的深拷贝

    // 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
    // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
    var arr1 = ["1","2","3"]; 
    var arr2 = arr1.slice(0);
    arr2[1] = "9";
    console.log("数组的原始值:" + arr1 );
    console.log("数组的新值:" + arr2 );

  • 用concat实现对数组的深拷贝

    // 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
    var arr1 = ["1","2","3"];
    var arr2 = arr1.concat();
    arr2[1] = "9";
    console.log("数组的原始值:" + arr1 );
    console.log("数组的新值:" + arr2 );
    // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
    var arr1 = [{a:1},{b:2},{c:3}];
    var arr2 = arr1.concat();
    arr2[0].a = "9";
    console.log("数组的原始值:" + arr1[0].a ); // 数组的原始值:9
    console.log("数组的新值:" + arr2[0].a ); // 数组的新值:9
  • 直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果

    function deepClone(initalObj, finalObj) {    
      var obj = finalObj || {};    
      for (var i in initalObj) {        
        var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
        if(prop === obj) {            
          continue;
        }        
        if (typeof prop === 'object') {
          obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
        } else {
          obj[i] = prop;
        }
      }    
      return obj;
    }

  • 使用扩展运算符实现深拷贝

    // 当value是基本数据类型,比如String,Number,Boolean时,是可以使用拓展运算符进行深拷贝的
    // 当value是引用类型的值,比如Object,Array,引用类型进行深拷贝也只是拷贝了引用地址,所以属于浅拷贝
    var car = {brand: "BMW", price: "380000", length: "5米"}
    var car1 = { ...car, price: "500000" }
    console.log(car1); // { brand: "BMW", price: "500000", length: "5米" }
    console.log(car); // { brand: "BMW", price: "380000", length: "5米" }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值