function的时候并不会拷贝过来。
浅度拷贝:复制一层对象的属性,并不包括对象里面的为引用类型的数据,当改变拷贝的对象里面的引用类型时,源对象也会改变。·
深度拷贝:重新开辟一个内存空间,需要递归拷贝对象里的引用,直到子属性都为基本类型。两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。
JavaScript存储对象都是存地址的,所以浅拷贝会导致 obj1 和obj2 指向同一块内存地址。改变了其中一方的内容,都是在原来的内存上做修改会导致拷贝对象和源对象都发生改变,而深拷贝是开辟一块新的内存地址,将原对象的各个属性逐个复制进去。对拷贝对象和源对象各自的操作互不影响。
var obj = {
a: 1,
b: 2
}
var obj1 = Object.assign(obj); //浅拷贝
console.log(obj === obj1) // true
var obj2 = Object.assign({}, obj);
console.log(obj === obj2) // false
深拷贝实现:
1. Array的slice和concat方法
Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。之所以把它放在深拷贝里,是因为它看起来像是深拷贝。而实际上它是浅拷贝。
var array = [1,2,3];
var array_shallow = array;
var array_concat = array.concat();
var array_slice = array.slice(0);
console.log(array === array_shallow); //true
console.log(array === array_slice); //false,“看起来”像深拷贝
console.log(array === array_concat); //false,“看起来”像深拷贝
2. JSON对象的parse和stringify, function不会拷贝过来。
var obj1 = [{
name: 'AAA',
childs: ['CC', 'VV']
}]
var obj2 = JSON.parse(JSON.stringify(obj1))
obj2[0].childs = []
console.log(obj1, obj2)
// [{childs: ["CC", "VV"], name: "AAA"}],
// [{childs: [], name: "AAA"}]
3.解构赋值 , 问题就是只能赋值一层
var obj1 = {a: 1, b: 2}
var obj2 = {...obj1}
obj2.a = 4
console.log(obj1, obj2)
// {a: 1,b: 2}
// { a: 4, b: 2}
var obj1 = [{
name: 'AAA',
childs: ['CC', 'VV']
}]
var obj2 = [...obj1]
obj2[0].childs = []
console.log(obj1, obj2)
console.log(obj1 === obj2) //false
//{ childs: [], name: "AAA"}]
//{ childs: [], name: "AAA"}]
4.递归
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
let a=[1,2,3,4],
b=deepClone(a);
a[0]=2;
console.log(a,b);