浅拷贝:在堆内存中创建内存,拷贝前后基本数据类型相互间不受影响,但引用类型会共享同一块内存,会相互影响。浅拷贝只能拷贝一层,如果对象有更深的层次就会互相影响。
深拷贝:从堆内存中开辟一个新的区域存放对象,所有类型相互间都不受影响。
实现浅拷贝的方法
1. Object.assign()
Object.assign(target, ...sources);
//target 为你要拷贝到的对象
//后面为一个或多个源对象,后者会被前者覆盖
let obj1 = { a: 1, b: 2 };
let obj2 = { b: 3, c: 4 };
let target = {};
Object.assign(target, obj1, obj2);
console.log(target); // 输出: { a: 1, b: 3, c: 4 }
2. 展开运算符…
他可以拷贝第一层,后续的就不行了
let obj1 = { name: 'Kobe', address:{x:100,y:100}}
let obj2= {... obj1}
obj1.address.x = 200;
obj1.name = 'wade'
console.log('obj2',obj2) // obj2 { name: 'Kobe', address: { x: 200, y: 100 } }
深拷贝的实现方式
1. 手撕
map的作用是为了解决循环嵌套的问题
//Deep Clone
function deepClone(target, map = new WeakMap()) {
if (target && typeof target === 'object') {
let cloneTarget = Array.isArray(target) ? [] : {}
if (map.has(target)) {
return map.get(target)
}
map.set(target, cloneTarget)
for (let key in target) {
cloneTarget[key] = deepClone(target[key], map)
}
// 处理 Symbol 属性
const symbols = Object.getOwnPropertySymbols(target);
for (const symbol of symbols) {
cloneTarget[symbol] = deepClone(target[symbol], map);
}
return cloneTarget
} else {
return target
}
}
2.lodash的_.cloneDeep
var _ = require('lodash');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);// false