博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS引用类型数据的浅拷贝与深拷贝
阅读量:6603 次
发布时间:2019-06-24

本文共 1145 字,大约阅读时间需要 3 分钟。

浅拷贝


之前文章提到,在定义一个对象或数组时,变量存放的往往只是一个地址。当我们对堆内存中的对象复制时,如果属性是对象或数组时,这时候我们拷贝的只是一个栈内存指针。因此b对象在访问该属性时,会根据指针寻找到a对象指向的堆内存对象,两者的属性值会指向同一内存空间

var a = {    key1:"11111"}function Copy(p) {    var c = {};    for (var i in p) {       c[i] = p[i];    }    return c;}a.key2 = ['小辉','小辉'];var b = Copy(a);b.key3 = '33333';alert(b.key1);     //1111111alert(b.key3);    //33333alert(a.key3);    //undefined//对象中key1属性是字符串,key2属性是数组。a拷贝到b,12属性均顺利拷贝。给b对象新增一个字符串类型的属性key3时,b能正常修改,而a中无定义。说明子对象的key3(基本类型)并没有关联到父对象中,所以undefined。b.key2.push("大辉");alert(b.key2);    //小辉,小辉,大辉alert(a.key2);    //小辉,小辉,大辉

但是,若修改的属性变为对象或数组时,那么对象之间就会发生关联。从以上弹出结果可知,对b对象进行修改,a、b的key2属性值(数组)均发生了改变。其在内存的状态,可以用下图来表示。

clipboard.png


深拷贝

不希望对象之间产生关联,那么这时候可以用到深拷贝。既然属性值类型是数组和或对象时只会传址,那么我们就用递归来解决这个问题,把要复制的对象中所有属于对象的属性类型都遍历赋给新对象即可。

function Copy(p, c) {    var c = c || {};    for (var i in p) {      if (typeof p[i] === 'object') {         c[i] = (p[i].constructor === Array) ? [] : {};         Copy(p[i], c[i]);      } else {         c[i] = p[i];      }    }    return c;    }    a.key2 = ['小辉','小辉'];var b={};b = Copy(a,b);        b.key2.push("大辉");alert(b.key2);    //小辉,小辉,大辉alert(a.key2);    //小辉,小辉

过程如下图

clipboard.png

转载地址:http://hjwso.baihongyu.com/

你可能感兴趣的文章
《Cadence 16.6电路设计与仿真从入门到精通》——导读
查看>>
Confluence 6 如何让我的小组成员知道那些内容是重要的
查看>>
找到一个适合的分布式文件系统之各种分布式文件系统优缺点对比
查看>>
httpd基本配置
查看>>
索引失效的几个原因
查看>>
关于多线程中使用while做循环而不使用if的解释
查看>>
欢迎你,企业基础架构CCIE,RS CCIEv5.0的升级版新时代迎合自动化运维的网工顶级认证...
查看>>
js typoeof用法
查看>>
五险一金,你清楚吗?
查看>>
Ip核_fifo
查看>>
基础 JavaScript 实例
查看>>
自定义pageControl
查看>>
repquota命令--Linux命令应用大词典729个命令解读
查看>>
我的友情链接
查看>>
设置vs解决方案跟随右边cpp
查看>>
Linux Administration
查看>>
如何使版面富有节奏感
查看>>
rabbitmq 管理及常用命令
查看>>
iphone导航控制器的开发与使用
查看>>
debian python library re-install
查看>>