深拷贝和浅拷贝
深拷贝和浅拷贝的区别
假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
- 深拷贝,是拷贝对象各个层级的属性,拷贝对象的地址。
例如:JSON.parse(JSON.stringify())
(特殊情况下无法使用,见文章末尾) - 浅拷贝,指针指向堆中相同的地址,所有会改变原来的数据。
例如:Object.assign()
Array.prototype.slice()
对象的扩展运算符(…)深拷贝还是浅拷贝
如果只是一层数组或是对象,其元素只是简单类型的元素,那么属于深拷贝(即只有一层拷贝)
let a = {
age: 22,
name: 'abc'
}
let b = {...a};
b.age = 18;
console.log(a.age); // 22
console.log(b.age); // 18如果数组或对象中的元素是引用类型的元素,那么就是浅拷贝
let a = {
age: 22,
name: 'abc',
address: {
city: 'Anhui'
}
}
let b = {...a};
b.address.city = 'Shanghai';
console.log(a.address.city); // Shanghai
console.log(b.address.city); // Shanghai如何使得深拷贝
const obj = {
age: 20,
name: 'dyk',
address: {
city: 'anqing'
},
arr: ['a', 'b', 'c']
}
// const obj1 = JSON.parse(JSON.stringify(obj))
const obj1 = deepClone(obj)
obj1.address.city = 'shanghai'
obj1.arr[1] = 666
console.log(obj, obj1)
function deepClone(obj) {
if (typeof obj !== 'object' || obj == null) {
return obj
}
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
//保证key不是原型的属性
if (obj.hasOwnProperty(key)) {
//递归
result[key] = deepClone(obj[key])
}
}
return result
}或者利用
JSON.parse(JSON.stringfy(xxx))
来实现深拷贝
注意:JSON.stringfy(xxx)
的方法无法处理函数和 undefined、无法处理循环引用、无法处理某些特殊的 JavaScript 对象,如 RegExp、Error、Date 等,这些对象会被转换成空对象、对象的原型链上的属性会丢失,如果原始对象的某个属性是通过原型链继承的,那么使用该方法得到的新对象会丢失该属性。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 青衣墨客!
评论