1. 对象的特殊性
因为对象的是通过指针仔细内存地址的,所以对象的拷贝不能像变量一般简单的赋值,对象的赋值只是将指针的地址赋值过去而已,修改属性值会对所有指向这个内存地址的对象的属性值都会被改变,见下面的例子:
// 变量赋值
var a = 5;
var b = a;
// 修改 b 不会对 a 造成影响
b=10;
> a
> 5
// 对象赋值
var obj = {
a: ‘5’,
b: ’10’,
c: {
d: 1
}
}
var obj1 = obj
// 修改 obj1.a 会对 obj.a 造成影响
obj1.a = 9
> obj.a
> 9
所以当你使用 object(array 也是 object 的一种特殊形式) 时,想复制一个 object,但两个 object 互不影响时,这就需要我们说的浅拷贝和深拷贝了
2. 最简单的实现 (有局限性)
// object 数据中只能有基本的数据类型(String,Number,Boolean,Array,object,null,undefined),如果有其它数据会丢失,但不会报错
obj1 = JSON.parse(JSON.stringify(obj))
3. 浅拷贝
基于 Object 的特殊性,在对对象进行简单的拷贝,只拷贝第一层级的属性,这种拷贝就是浅拷贝。
function Copy(source, obj) {
for (let key in obj) {
source[key] = obj[key]
}
return source
}
Copy(obj1, obj)
obj1.a=10
obj1.c.d=100
// 浅拷贝对第一层的属性进行了拷贝,所以 obj.a 不受影响
> obj.a = 9
// 但是 obj.c.d 是第二层级的属性,它受到了影响,它的值被改变了
> obj.c.d =100
3. 深拷贝
// extendEasy 实现深拷贝;extendSuper 在深拷贝的基础上实现多个继承类似(source, obj1, obj2, obj3 …)
function extendSuper () {
var arg = arguments
for (let i = 1; i < arg.length; i++) {
arg[0] = extendEasy(arg[0], arg[i])
}
return arg[0]
}
// 实现深拷贝
function extendEasy (source, obj) {
for (let key in obj) {
if (obj[key] instanceof Object) {
source[key] = {}
source[key] = extendEasy(source[key], obj[key])
}
if (obj[key] instanceof Array) {
source[key] = []
source[key] = extendEasy(source[key], obj[key])
}
source[key] = obj[key]
}
return source
}