浅拷贝: 如果是数组,可以使用数组的一些方法实现:slice(),concat()
// 浅拷贝 是原始对象的第一层属性的精准拷贝
let obj = { name: 'admin', age: 18, foo: { id: 10001 } };
function shallowCopy(src) {
const dist = {};
for (let prop in src) {
if (src.hasOwnProperty(prop)) {
dist[prop] = src[prop];
}
}
return dist;
}
let obj2 = shallowCopy(obj);
obj.foo = { id: 1002 };
console.log(obj2);
// 结果为{name: 'admin', age: 18, foo: {…}}
// age: 18
// foo:
// id: 10001
// name: "admin"
深拷贝:指针赋值,并且内容拷贝、浅拷贝:只是简单的指针赋值 数组
// 深拷贝 是原始对象的所有层级的精准拷贝
// 深拷贝出来的对象和原始对象无法数据共享
function deepCopy(src) {
if (typeof src != 'object') return src;
const dist = Array.isArray(src) ? [] : {};
for (let prop in src) {
if (src.hasOwnProperty(prop)) {
if (typeof src[prop] == 'object') {
dist[prop] = deepCopy(src[prop])
} else {
dist[prop] = src[prop];
}
}
}
return dist;
}
let obj = {name:'admin', age:18, foo:{id:10001}};
obj.foo = {id:1002};
console.log(deepCopy(obj));
// 结果:
// {name: 'admin', age: 18, foo: {…}}
// age: 18
// foo: {id: 1002}
// name: "admin"
JSON.parse(JSON.stringify())不仅适用于数组还适用于对象。不能拷贝函数,undefined,symbol。
// 用JSON只能深拷贝到属性name:'admin', age:18,无法实现对对象中方法的深拷贝foo:{id:10001}
let obj2 = {name:'admin', age:18, foo:{id:10001}};
function deepCopy(src) {
let stringOfObj = JSON.stringify(src);
return JSON.parse(stringOfObj)
}
console.log(deepCopy(obj2));
什么时候用深拷贝 /浅拷贝
无论深浅,都是需要的,当深拷贝发生时通常表明存在着一个聚合关系,当浅拷贝发生时,通常表明存在着相识关系。
举个简单例子:当实现一个组合模式 Composite Pattern 时通常都会实现深拷贝;当实现一个观察者模式 Observer Pattern,时,就需要实现浅拷贝。