关于javascript:JS深拷贝与浅拷贝

5次阅读

共计 1173 个字符,预计需要花费 3 分钟才能阅读完成。

如何辨别深拷贝与浅拷贝,简略点来说,就是假如 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 存储数组对象

正文完
 0