浅拷贝:指向被复制的内存地址,如果原地址里的值发生改变,那么浅拷贝出来的值也会发生改变。
深拷贝:开辟一块新的内存地址,存放复制出来的对象。如果原地址里的值发生改变,那么对深拷贝出来的对象没影响。
数组的浅拷贝:concat,slice,[…],Array.from,Object.assign([],arr),map(item=>({…item}))
对象的浅拷贝:Object.assign({},obj),{…}
深拷贝:Json.parse(Json.stringify())不能拷贝函数,_.cloneDeep,
let arr = [{ width: 100 }];
let obj = { key: { value: 1 } }
1.浅拷贝
浅拷贝只是拷贝了数据的第一层,对第一层进行了深拷贝(基本数据类型),但对于多层次来说就是浅拷贝,总的来说是浅拷贝
let concat = arr.concat();
let slice = arr.slice();
let extend = [...arr];
let from = Array.from(arr);
//Object.assign拷贝可枚举的对象,
let assign = Object.assign([], arr);
let assignObj = Object.assign({}, obj);
arr[0].width = 200;
obj.key.value = 2;
console.log("concat:", concat); //[{ width: 200 }];
console.log("slice:", slice); //[{ width: 200 }];
console.log("extend:", extend); //[{ width: 200 }];
console.log("from:", from); //[{ width: 200 }];
console.log("assign:", assign); //[{ width: 200 }];
console.log("assignObj:", assignObj); // { key: { value: 2 } }
2.深拷贝
let deep = JSON.parse(JSON.stringify(arr));
console.log("deep:", deep); //[{ width: 100 }];
3.自定义深拷贝
function deepCopy(obj) {
let newObj;
// 判断是什么类型
if (typeof (obj) === 'object' && obj !== null) {
newObj = obj.constructor === Object ? {} : []
for (let key in obj) {
//再判断内部是啥类型,层层递归
if (typeof (obj[key]) === "object" && obj[key] !== null) {
newObj[key] = deepCopy(obj[key])
} else {
newObj[key] = obj[key]
}
}
} else {
newObj = obj
}
return newObj
}
名称 | 和原数据是否指向同一对象 | 原数据为基本数据类型 | 原数据中包含子对象 |
---|---|---|---|
赋值 | 是 | 改变会使原数据一同改变 | 改变会使原数据一同改变 |
浅拷贝 | 否 | 改变不会使原数据一同改变 | 改变会使原数据一同改变 |
深拷贝 | 否 | 改变不会使原数据一同改变 | 改变不会使原数据一同改变 |