搜索
写经验 领红包
 > 育儿

javascipt浅拷贝和深拷贝(javascipt深拷贝和浅拷贝的区别)

导语:Javascript 浅拷贝/深拷贝

拷贝功能是编程中的一个常用操作,主要分为深拷贝和浅拷贝,但也是经常容易犯错的一个知识点,今天来谈谈Javascript中的拷贝功能。在JS中,常见的字符串拷贝操作是这样的:

str1 = &39;;str2 = str1;console.log(str1);str2 = &39;;console.log(str1);console.log(str2);

非常简单,输出结果如下:

123123456

下面来看一段浅拷贝的例子:

obj1 = {a: 1};obj2 = obj1;console.log(obj2.a);obj2.a = 2;console.log(obj2.a);console.log(obj1.a);

输出结果:

122

上面的代码可以看到,当我们把obj1赋值给obj2的后,改变了obj2中属性a的值,发现obj1中的a同样被改变了,因为当把obj1赋值给obj2后,obj1和obj2指向了同一个地址,这时候obj2和obj1是共享同一个内存空间的,可以参考下面的这种图:

所以改变obj2中的a,相当于改变了obj1中的a,这就是浅拷贝;

接着来看下深拷贝如何实现:

obj1 = {a: 1, b: {c: 2}};obj2 = JSON.parse(JSON.stringify(obj1));obj2.b.c = &39;;console.log(obj1.b.c);

输出结果:

2

可以看到通过把对象进行1次序列化+反序列化,把obj1赋值给obj2,然后修改obj2对象中的属性值,最后发现obj1中的属性值并没有改变,因为obj1和obj2独享自己的一份内存空间,这就实现了深拷贝操作,可以参照下面的这张图:

但是,上面的深拷贝方式其实是有问题的,不推荐这种写法,因为这种写法不能覆盖所有的深拷贝情况,来看几个反例:反例1: 当要拷贝的对象中包含undefined的属性

obj1 = {    a: 1,     b:     {        c: 2,        d: undefined    }}obj2 = JSON.parse(JSON.stringify(obj1))console.log(obj2)

输出结果:

{    : 1,    : {        : 2    }}

从输出结果会发现拷贝后的obj2对象缺失了属性d。

反例2: 当要拷贝的对象中包含function属性

obj1 = {    a: 1,     b:     {        c: 2,        d: function name(params) {            console.log(params);        }    }}obj2 = JSON.parse(JSON.stringify(obj1))console.log(obj2)

输出结果:

{    : 1,    : {        : 2    }}

从输出结果会发现拷贝后的obj2对象缺失了属性d。反例3: 当要拷贝的对象中包含对象属性

obj1 = {    a: 1,     b:     {        c: 2,        d: new RegExp(&39;)    }}obj2 = JSON.parse(JSON.stringify(obj1))console.log(obj2)

输出结果:

{    : 1,    : {        : 2,        : {}    }}

从输出结果会发现拷贝后的obj2对象缺失了属性d。从上面的3个反例中可以看到JSON.parse(JSON.stringify())这种方式并不适合用来做深拷贝。下面来介绍在Javascript中深拷贝的正确姿势:

const _ = require(&39;);const externalObject = {  animal: &39;};const originalObject = {  a: 1,  b: &39;,  c: false,  d: externalObject};const deepClonedObject = _.clonedeep(originalObject);externalObject.animal = &39;;console.log(originalObject);console.log(deepClonedObject);

输出结果:

{ a: 1, b: &39;, c: false, d: { animal: &39; } }{ a: 1, b: &39;, c: false, d: { animal: &39; } }

从输出结果可以看到,用lodash这个三方库中的clonedeep方法做到了对象的深度拷贝,拷贝后的对象和原对象做到了完全的隔离,如果要完成深拷贝的功能,推荐使用这种方式。以上主要介绍了Javascript中深拷贝和浅拷贝的常见用法和误区。

免责声明:本站部份内容由优秀作者和原创用户编辑投稿,本站仅提供存储服务,不拥有所有权,不承担法律责任。若涉嫌侵权/违法的,请反馈,一经查实立刻删除内容。本文内容由快快网络小碧创作整理编辑!