只有对象里嵌套对象的情况下,才会根据需求讨论,我们要深拷贝还是浅拷贝,普通非嵌套对象的拷贝无深浅之分
浅拷贝
var obj2 = shallowCopy( obj1 , {})
console.log( obj1 !== obj2 ) // true 无论哪种拷贝,obj1和obj2一定都是2个不同的对象(内存空间不同)
console.log( obj2.arr === obj1.arr ) // true 他们2个对象里arr的引用,指向【相同的】内存空间
调用shallowCopy()后, obj2 拷贝 obj1 所有的属性。但是obj2.arr和obj1.arr是不同的引用,指向同一个内存空间
代码实现:
function shallowCopy(source, target = {}) {
var key;
for (key in source) {
if (source.hasOwnProperty(key)) { // 意思就是__proto__上面的属性,我不拷贝
target[key] = source[key];
}
}
return target;
}
深拷贝
var obj2 = deepCopy( obj1 , {})
console.log( obj1 !== obj2 ) // true 无论哪种拷贝,obj1和obj2一定都是2个不同的对象(内存空间不同)
console.log( obj2.arr === obj1.arr ) // false 他们2个对象里arr的引用,指向【不同的】内存空间
调用deepCopy()后,obj2拷贝obj1所有的属性,而且obj2.arr和obj1.arr是指向不同的内存空间,
2个obj2除了拷贝了一样的属性,没有任何其他关联。这种我们叫深拷贝。
代码实现:
- 深拷贝,就是遍历那个被拷贝的对象
- 判断对象里每一项的数据类型
- 如果不是对象类型,就直接赋值,如果是对象类型,就再次调用deepCopy,递归的去赋值
function deepCopy( source ) {
let target = Array.isArray( source ) ? [] : {}
for ( var k in source ) {
if ( typeof source[ k ] === 'object' ) {
target[ k ] = deepCopy( source[ k ] )
} else {
target[ k ] = source[ k ]
}
}
return target
}
实JQ里已经有$.extend()函数,实现就是深拷贝和浅拷贝的功能
参考文章:一篇文章彻底说清JS的深拷贝and浅拷贝