什么是深拷贝

  • Post author:
  • Post category:其他


深拷贝:创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”,新对象跟原对象不共享内存,修改新对象不会改到原对象

浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用




一、深拷贝是什么?


1.概念: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”,新对象跟原对象不共享内存,修改新对象不会改到原对象



为什么使用深拷贝

我们希望在改变新的数组(对象)的时候,不会改变原数组(对象)



数组:

三种方法

第一种:直接遍历

var array = [1, 2, 3, 4];
function copy (array) {
   let newArray = []
   for(let item of array) {
      newArray.push(item);
   }
   return  newArray;
}
var copyArray = copy(array);
copyArray[0] = 100;
console.log(array); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]

直接遍历push到新的数组里面

第二种: slice()方法

var array = [1, 2, 3, 4];
var copyArray = array.slice();
copyArray[0] = 100;
console.log(array); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]

slice()方法返回的是从一个已经有的数组里面截取一部分元素作为新的数组(不改变原数组)

第三种:concat()

var array = [1, 2, 3, 4];
var copyArray = array.concat();
copyArray[0] = 100;
console.log(array); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]

concat()用于连接两个或多个数组 (不会改变原数组)



对象:

第一种:直接遍历

第二种:ES6的Object.assign

var obj = {
  name: '张三',
  job: '学生'
}
var copyObj = Object.assign({}, obj);
copyObj.name = '李四';
console.log(obj);   // {name: "张三", job: "学生"}
console.log(copyObj);  // {name: "李四", job: "学生"}
 

用于对象的合并,将源对象的所有可枚举属性,复制到目标对象

第三种:ES6扩展运算符:

扩展运算符(…)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中

对多层嵌套对象,很遗憾,上面三种方法,都会失败:

var obj = {
   name: {
      firstName: '张',
      lastName: '三'
   },
   job: '学生'
}
 
var copyObj = Object.assign({}, obj)
copyObj.name.lastName = '三三';
console.log(obj.name.lastName); // 三三
console.log(copyObj.name.lastName); // 三三
 

用于取出参数对象的所有可遍历属性,拷贝到当前对象之中



手写深拷贝
function  Clone(val){
if(typeof val !== 'object' || val ==null){
return val;
}
let obj;
if(val instansof Array){
obj =[]
}else{
 obj = {};
}
for (var key in val){
if(val.hasOwnProperty(key)){
obj[key] = Clone(val[key])
}
}
return obj
}
var a ={b:[1,2,3,{c:[4,5,{d:'helloword'}]}]}
var b= Clone(a)
console.log(b)



版权声明:本文为weixin_57998947原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。