如何辨别深拷贝与浅拷贝,简略点来说,就是假如B复制了A,当批改A时,看B是否会发生变化,如果B也跟着变了,阐明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

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);

这里再次强调,深拷贝,是拷贝对象各个层级的属性,能够看个例子。JQ里有一个extend办法也能够拷贝对象,咱们来看看
let a=[1,2,3,4],

b=a.slice();

a[0]=2;
console.log(a,b);

那是不是说slice办法也是深拷贝了,毕竟b也没受a的影响,下面说了,深拷贝是会拷贝所有层级的属性,还是这个例子,咱们把a改改
let a=[0,1,[2,3],4],

    b=a.slice();

a[0]=1;
a2=1;
console.log(a,b);

拷贝的不彻底啊,b对象的一级属性的确不受影响了,然而二级属性还是没能拷贝胜利,依然脱离不了a的管制,阐明slice基本不是真正的深拷贝。
这里援用知乎问答外面的一张图

第一层的属性的确深拷贝,领有了独立的内存,但更深的属性却依然专用了地址,所以才会造成下面的问题。
同理,concat办法与slice也存在这样的状况,他们都不是真正的深拷贝,这里须要留神。

除了递归,咱们还能够借用JSON对象的parse和stringify

function deepClone(obj){

let _obj = JSON.stringify(obj),    objClone = JSON.parse(_obj);return objClone

}
let a=[0,1,[2,3],4],

b=deepClone(a);

a[0]=1;
a2=1;
console.log(a,b);

能够看到,这下b是齐全不受a的影响了。
附带说下,JSON.stringify与JSON.parse除了实现深拷贝,还能联合localStorage实现对象数组存储。有趣味能够浏览博主这篇文章。
localStorage存储数组,对象,localStorage,sessionStorage存储数组对象