资讯专栏INFORMATION COLUMN

JS中把对象赋值给变量时出现的问题

miguel.jiang / 3361人阅读

摘要:问题刚才碰到了一个这样的问题有一个由对象组成的数组,把其中一个对象赋值给变量,然后改变了的属性,对应的原来数组中的对象的属性也会随之改变。

问题

刚才碰到了一个这样的问题:有一个由对象组成的数组,把其中一个对象赋值给变量p,然后改变了p的属性,对应的原来数组中的对象的属性也会随之改变。

var arr = [{x:0, y:0}, {x:0, y:0}]
var p = arr[0]
p.x = 1
p.y = 2
console.log(arr) // [{x:1, y:2}, {x:0, y:0}]
探究

我一开始以为这是数组的什么神奇特性,经过几番试验发现只有由对象组成的数组有这个问题,隐隐觉得这是对象的某个特性,然后又试了下,果然如此!

var a = {x:0, y:0}
var p = a
p.x = 1
console.log(a) // {x:1, y:0}

a赋值给变量p之后,改变p的某个属性,a中对应的属性也会随之改变。

原因

简单地想了一下原因,不知道正确不正确:
var p = a是让p指向了a所代表的对象。同理,var a = {x:0, y:0}是让a指向了{x:0, y:0}这样一个对象。所以实际上pa指向的是同一个对象,修改其它们中任何一个都会使另一个一同改变。

解决办法

那有没有让p改变之后a保持不变的办法呢?
有的!

var a = {x:0, y:0}
var p = {}
p.x = a.x
p.y = a.y

通过这种方式把a的属性一一对应地赋值给p,之后对p做出的任何修改都不会影响到a。但是这种方法很麻烦,特别是碰到属性很多的对象,那么可以写个函数来完成这个工作:

function cloneObj(obj) {
  var newObj = {}
  for(var prop in obj) {
    newObj[prop] = obj[prop]
  }
  return newObj
}
var a = {x:0}
var p = cloneObj(a)
p.x = 2
console.log(p) // {x:2}
console.log(a) // {x:0}

成功了!修改p的属性之后a的属性没有随之改变。

后来网上查了查,发现js中有深拷贝和浅拷贝这样的区分,粗粗看了一遍。但是没有更多的实际使用经验所以理解也不是很深刻,如果以后有了更深的见解的话到时候再来写一篇。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88147.html

相关文章

  • 每日 30 秒 ⏱ 谁敢与我一战

    showImg(https://segmentfault.com/img/remote/1460000018771037?w=900&h=500); 简介 benchmark、基准测试、jsPerf 在 优雅插入数组 一文中大家最多的评论就是 能不能加个基准测试。小二不是不喜欢加基准测试而是现在硬件设备的性能越来越快了,有时候一些操作不是性能问题的主要原因,当然这不是我们不写出好代码的理由。 书写...

    Dionysus_go 评论0 收藏0
  • 关于Keystone.js安装时出现的一个新手可能会遇到的小问题的解决方法

    摘要:在执行如下命令之后如果你的电脑没有装,那么执行就会出现如下的显示不是内部或外部命令,也不是可运行的程序或批处理文件。是制作的生成器需要,官网是。使用来生成网站,如果没有安装的话,需要使用进行安装。解决方法安装后即可 在terminal执行如下命令之后 npm install -g generator-keystone 如果你的电脑没有装yo,那么执行 yo keystone 就会出...

    quietin 评论0 收藏0
  • 坑爹微信之读取PKCS12流时出现的java.io.IOException: DerInputStr

    摘要:背景微信退款接口需要使用到证书,我参考微信的官方进行,部分代码如下上面的代码,在本地调试的时候正常跑过,没有出现任何异常,但是放到测试环境之后便会出现下面的异常,这三种异常都是从这里抛出来的。 背景 微信退款接口需要使用到证书,我参考微信的官方Demo进行,部分代码如下: char[] password = config.getMchID().toCharArray(); InputS...

    calx 评论0 收藏0
  • #JavaScript# IE兼容

    摘要:出现原因在子页面关闭时,会释放掉在子页面中声明赋值的对象。所以在父页面所有对这个对象的引用操作都会产生这个错误。然后在父页面中使用变成对象。 在IE浏览器中出现的问题 1.不能执行已释放 Script 的代码 1.bug出现背景:在使用iframe标签时,如果子页面向父页面传递在子页面创建的对象(所有对象,包括数组,函数,正则等)时,会出现这个bug。 2.bug出现原因: 在子页面关...

    Me_Kun 评论0 收藏0
  • centos使用chrome-cli、chromium或wkhtmltoimage截图时出现的中文字

    摘要:后来换了各种系统环境,包括更改中文支持,依然如故,只有在自己的上是正常的。查看是否有中文字体,一般情况下是不存在的,否则也不会乱码。再一次运行程序脚本,查看截图是否包含正常的中文字符。 在centos7环境下使用chrome-php或wkhtmltoimage截图时出现的中文乱码解决方案 最近做了一个小项目,要求使用chrome/chromium对抓取的页面进行截图保存并上传云服务,因...

    ivyzhang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<