共计 1994 个字符,预计需要花费 5 分钟才能阅读完成。
咱们晓得,JavaScript 的数据类型分为根本数据类型和援用型数据类型。
对于根本数据类型而言,并没有深浅拷贝的区别,这里所说的深浅拷贝是针对援用型数据类型的。
浅拷贝:
只是简略的复制(赋值),不会开拓新栈,复制的后果是两个对象都指向同一个地址,批改任意一个对象的属性,另外一个对象的属性也跟着该扭转。```
const = originArray = [1,2,3,4,5];
const = originObj = {a:'a',b:'b',c:[1,2,3]};
const cloneArray = originArray;
const cloneObj = originObj;
console.log(cloneArray); //[1,2,3,4,5]
console.log(originObj); //{a:'a',b:'b',c:Array[3]}
cloneArray.push(6);
cloneObj.a = {aa:'aa'};
console.log(cloneArray); //[1,2,3,4,5,6]
console.log(originArray); //[1,2,3,4,5,6]
console.log(cloneObj); //{a:{aa:'aa'},b:'b',c:Array[3]}
console.log(originObj); //{a:{aa:'aa'},b:'b',c"Array[3]}
```
深拷贝:
开拓新栈,两个对象对应两个不同的地址,扭转其中一个对象的属性,另外一个对象的属性不产生扭转。
深拷贝的实现办法:
1、利用 JSON 对象中的 parse 和 stringfy
2、利用递归来实现每一层都从新创建对象并赋值
JSON.stringfy(); 将一个 JavaScript 值转为一个 JSON 字符串
JSON.parse(); 是将一个 JSON 字符串转成一个 JavaScript 值或对象
第一种办法实现:const originArray = [1,2,3,4,5];
const cloneArray = JSON.parse(JSON.stringfy(originArray));
console.log(cloneArray === originArray);//false
const originObj = {a:'a',b:'b',c:[1,2,3]};
const cloneObj = JSON.parse(JSON.stringfy(originObj));
console.log(cloneObj === originObj);//false
cloneObj.a = 'aa';
cloneObj.c = [1,1,1];
console.log(cloneObj); //{a:'a',b:'b',c:[1,1,1]}
console.log(originObj); //{a:'a',b:'b',c:[1,2,3]}
然而这种办法并不欠缺,undefined、function、symbol 会在转换过程中被疏忽。如果对象中有函数时,就不能用这个办法进行深拷贝。第二种办法实现:function deepClone(source){const targetObj = source.constructor === Array ? []:{}; // 判断复制的指标是对象还是数组
for(let keys in source){if(source.hasOwnProperty(keys)){if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
targetObj[keys] = source[keys].constructor === Array?[]:{};
targetObj[keys] = deepClone(source[keys]);
}else{ // 如果不是,就间接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
const originObj = {
name:'xiaochaochao',
say:function(){console.log('hello world');
}
}
console.log(originObj); //{name:'xiaochaochao',say:f}
const cloneObj = deepClone(originObj);
console.log(cloneObj);//{name:'xiaochaochao',say:f}
JavaScript 中的拷贝 (都是 浅拷贝):
concat(); slice();
es6 新增的 obj.assign(); ...( 扩大运算符)
总结:
1、赋值运算符进行的是浅拷贝
2、JavaScript 中的四种办法看起来是深拷贝,但其实是浅拷贝
3、JSON.stringfy 是深拷贝
4、递归能够实现全副的深拷贝
正文完