关于javascript中的深拷贝和浅拷贝

        关于javascript中的深拷贝和浅拷贝,有很多种说法:深克隆浅克隆、深复制浅复制,其实说的都是那么一回事。在这里我就说深拷贝和浅拷贝。

        什么东西要做这个拷贝操作呢?就是对象。因为我们在声明变量并初始化变量为对象的时候,实质上给它的值是一个指向实际对象的指针,一个地址而已,例如:

var a;
a = {test:123};

        这个a,实际上是一个对象指针,它指向的是{ “test”:123 }这个对象,那如果我想多拷贝一份b呢?

var a;
a = {test:123};
var b = a;
console.log(b);   //{test:123}

        好了,你也拷贝了一份给b了,那如果你改变一下b对象的内容,a对象又会怎样呢?

var a;
a = {test:123};
var b = a;
b.test = 321;
console.log(b);   //{test:321}
console.log(a);   //{test:321}

        我们可以看到,你改变b对象内容,a的对象也会被改变了,因为你只是复制了a的地址给b,而这个地址,都同时指向了同一个对象,所以你通过b地址改变对象,实际上a地址对应的对象就改变了。

        这个拷贝,就是我们说的浅拷贝,你拷贝的只是一个指针,它指向的还是这个对象。这个是否和我们有时候写的函数有点像:

var a = {test:123};
function example(b){
    b.test = 321;
    return b;
}
console.log(example(a));   //{test:321}
console.log(a);   //{test:321}

        这个example中的形参b,实际上就是拷贝了一份a的指针过来,然后操作,再返回一个对象,其实返回的这个对象,就是a指向的那个对象,但是通过b地址改变了。

        所以有时候我们在写函数的时候,特别对于传入的对象,如果单纯以为传入的是整个对象那就很危险了,因为你的操作很可能造成对原对象的影响,所以不要忽视这一个问题。

        好了,我们知道了这样是浅拷贝,那如何是深拷贝呢?

        其实很简单,就是不仅拷贝多一份地址,还要拷贝多一份对象,整个对象。这里有一个简单粗暴的方法:

var a = {test:123};
var b = JSON.parse(JSON.stringify(a));
b.test = 321;
console.log(a); //{test:123}
console.log(b); //{test:321}

        通过先用JSON.stringify方法转为字符串,然后再用JSON.parse方法转为对象,当然了,更妥当的方法,就是采用遍历的方法,将每一个属性都复制给一个新的对象,或者可以采用lodash模块中的克隆方法,可以选择不同程度的克隆深度,也是非常好的方法。

        关于javascript中的深拷贝和浅拷贝,重点是无论任何情况,都不要轻易直接将对象地址复制给新的变量,因为你操作的这个地址指向的对象,很可能被你改变了,到你回过头来再用原来对象的时候,发觉已经被你改变了。

文章在我的github上的地址:点击跳转

原创文章,转载请注明出处!

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行许可。

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据