1、区分:
一种是MDN社区规范。
就是维度度意思,浅拷贝只能复制一层,深拷贝可以复制多层
let arr1 = [1, 2, 3]
let arr2 = arr2;
// 这个叫赋值,赋的是引用
// arr1和arr2指向同一块内存空间
let arr3 = arr1.slice();
// 这个叫浅拷贝,实际上a和b是两块内存空间
2、Array.slice()
let a = [{ name: 'orange', age: 18 }]
// 为什么说是浅的,引入如果a不长这样,而是数组里面嵌套一个对象,slice就无法剥离引用
let b = a.slice();
a[0].name = 'lwx'
console.log(a); // [ { name: 'lwx', age: 18 } ]
console.log(b); // [ { name: 'lwx', age: 18 } ]
3、Object.assign()
let obj1 = {
a: 0,
b: {
c: 0
}
};
let obj2 = Object.assign({}, obj1);
obj2.b.c = 3;
console.log(obj1); // { a: 0, b: { c: 3 } }
console.log(obj2); // { a: 0, b: { c: 3 } }
// 只拷贝源对象的自身属性(不拷贝继承属性)
// 不会拷贝对象不可枚举的属性
// undefined和null无法转成对象,他们不能作为Object.assign参数,但是可以作为源对象
// 属性名为Symbol 值的属性,可以被Object.assign拷贝
4、JSON来回切换
let obj3 = JSON.parse(JSON.stringify(obj1));
// 虽然来回序列化可以快速实现深拷贝但是解决不了循环引用和平台数据类型的问题
5、深度克隆
// 深度克隆
function deepClone(source) {
// 如果类型不是对象
if (typeof source != "object") {
return source;
}
// 如果为null
if (source == null) {
return source;
}
var newObj = (source.constructor === Array) ? [] : {}; //开辟一块新的内存空间
for (var i in source) {
newObj[i] = deepClone(source[i]);
}
return newObj;
}