深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级
一、浅拷贝(一层):仅仅是复制了引用,彼此之间的操作会互相影响
1. Object.assign
let obj = { a:1, arr:[2,3]};
let res = Object.assign({}, obj)
2. 扩展运算符
let obj = { a:1, arr:[2,3]};
let res = {...obj};
3. 浅拷贝原生实现
const shallowCopy = (sourceObj) => {
if (typeof sourceObj !== 'object') return;
let newObj = sourceObj instanceof Array ? [] : {};
for(let key in sourceObj){
if(sourceObj.hasOwnProperty(key)) {
newObj[key] = sourceObj[key];
}
}
return newObj;
}
let obj = { a:1, arr:[2,3]};
let res = shallowCopy(obj);
二、深拷贝(多层):在堆中重新分配内存,不同的地址,相同的值,互不影响
1. JSON 序列化
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
2. 深拷贝的原生实现
const deepCopy = (sourceObj) => {
if(typeof sourceObj !== 'object') return;
let newObj = sourceObj instanceof Array ? [] : {};
for(let key in sourceObj){
if(sourceObj.hasOwnProperty(key)) {
newObj[key] = (typeof sourceObj[key] === 'object' ? deepCopy(sourceObj[key]) : sourceObj[key]);
}
}
return newObj;
}
三、Array 中的拷贝
1. Array.prototype.slice()
let a = [1, 2, 3, 4];
let b = a.slice();
2. Array.prototype.concat()
let a = [1, 2, 3, 4];
let b = a.concat();
Array 的 slice 和 concat 方法并不是真正的深拷贝,对于 Array 的第一层的元素是深拷贝,而 Array 的第二层 slice 和 concat 方法是复制引用。所以,Array 的 slice 和 concat 方法都是浅拷贝。