我对深浅拷贝的理解,以及实现一个对数组和对象深拷贝的方法

参考文档:
MDN
深浅拷贝

为什么要进行拷贝

var obj1={
    value: 'a'
}
var obj2 = obj1;
obj2.value='b';
console.log(obj1);//{ value: 'b' }

因为对象是引用类型,所以赋值时的操作仅是赋予相同的地址,当对其中一个对象进行操作时,就会影响其他的对象。解决这个问题就需要拷贝了。我们希望在改变新的数组(对象)的时候,不改变原数组(对象)。

浅拷贝

使用原生的Object.assign() 方法就可以实现浅拷贝

let obj1={
    value: 'a'
}
let obj2 = Object.assign({},obj1);
obj2.value='b';
console.log(obj1);//{ value: 'a' }

当然我们也可以通过展开运算符(…)来解决

let obj1={
    value: 'a'
}
let obj2 = {...obj1};
obj2.value='b';
console.log(obj1);//{ value: 'a' }

但是如果拷贝的源对象当中包含对象时,OBject.assign()方法只会拷贝对象的引用地址

let obj1={
    value: 'a',
    obj3:{
        value2: 'c'
    }
}
let obj2 = Object.assign({},obj1);
obj2.obj3.value2='b';
console.log(obj1);//{ value: 'a', obj3:{ value2: 'b' } }

深拷贝

如果要拷贝的对象中包含对象,就需要深拷贝了,一般使用原生的方法JSON.parse(JSON.stringify(obj))

obj1={
    value: 'a',
    obj3:{
        value2: 'c'
    },
    arr:[1,2,3]
}
let obj2 = JSON.parse(JSON.stringify(obj1));
obj2.obj3.value2='b';
obj2.arr[0]= "a";
console.log(obj2);//{ value: 'a', obj3:{ value2: 'b' }, arr:['a',2,3] }
console.log(obj1);//{ value: 'a', obj3:{ value2: 'c' }, arr:[1,2,3] } 没有发生改变

使用JSON.stringify进行深拷贝有一些弊端

使用JSON.stringify进行深拷贝的弊端

1.如果 obj 里面有时间对象,则 JSON.stringify 后再 JSON.parse 的结果,时间将转为字符串的形式,而不是对象的形式,可以采用递归进行遍历
let obj = {
    a:123,
    b:[new Date(),new Date()]
}
let newObj = JSON.parse(JSON.stringify(obj));
console.log(obj,newObj); // 此时输出的时间为字符串
2.如果 obj 里有 RegExp (正则表达式的缩写)、Error 对象,则序列化的结果将只得到空对象;
let obj = {
    a:123,
    b:/aabb[a-z]\d/,
    c:new TypeError('typeError')
}
let newObj = JSON.parse(JSON.stringify(obj));
console.log(obj,newObj);

递归实现深拷贝

function deepClone1(obj) {
  //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
  var objClone = Array.isArray(obj) ? [] : {};
  //进行深拷贝的不能为空,并且是对象或者是
  if (obj && typeof obj === "object") {
    for (key in obj) {
      if (obj.hasOwnProperty(key)) {
        if (obj[key] && typeof obj[key] === "object") {
          objClone[key] = deepClone1(obj[key]);
        } else {
          objClone[key] = obj[key];
        }
      }
    }
  }
  return objClone;
}

concat(数组的深拷贝)

实现一个对数组和对象的深拷贝的方法

var obj={
    name: 'znl',
    age: 18,
    friend:{
        name: 'borys',
        age: 20
    },
    arr:[1,2,[3,4]]
}

function copy(obj){
    var type=Object.prototype.toString.call(obj);
    if(!(type == '[object Array]' || type == '[object Object]')){
        return 'Type Error!';
    }
    return JSON.parse(JSON.stringify(obj));
}

var obj2= copy(obj);
console.log(obj.friend === obj2.friend)//false
console.log(obj.arr === obj2.arr)//false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值