为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript代码技巧:foo.x的值是什么

JavaScript代码技巧:foo.x的值是什么

桃花长相依 2019-12-13 15:10:33
我在GitHub前端面试问题集中发现了这个问题:var foo = {n: 1};var bar = foo;foo.x = foo = {n: 2};问题:foo.x的值是什么?答案是undefined。我已经进行了一些研究,并且我理解这个问题(如果我错了,请纠正我):var foo = {n: 1};声明一个foo属性n等于1 的对象。var bar = foo;声明一个对象bar,该对象引用与相同的对象foo。foo.x = foo = {n: 2}; 我相信等于 foo.x = (foo = {n: 2});然后我foo.x等于undefined。但是,的值bar.x是object {n:2}。如果bar和foo引用相同的对象,为什么在bar.x得到值却foo.x是undefined?真正发生了foo.x = foo = {n: 2};什么?
查看完整描述

3 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

foo.x = foo = {n: 2};

判定foo.x是指一种属性x的的{n: 1}目的,分配{n: 2}给foo,并分配的新值foo- {n: 2}-为属性x的的{n: 1}对象。


重要的是,foo这foo.x指的是之前确定foo的变化。


参见ES5规范的11.13.1节:


令lref为评估LeftHandSideExpression的结果。


令rref为评估AssignmentExpression的结果。


赋值运算符从右到左关联,因此您得到:


foo.x = (foo = {n: 2})

首先评估左侧,然后评估右侧。



查看完整回答
反对 回复 2019-12-14
?
LEATH

TA贡献1936条经验 获得超6个赞

foo.x = foo = {n:2};


此处foo指的是赋值之前即执行语句之前的{n:1}对象。


该语句可以重写为foo.x =(foo = {n:2});


在对象方面,以上语句可以重写为 {n:1} .x =({n:1} = {n:2});


由于分配仅从右到左发生。因此,这里我们只需要在执行开始之前检查foo是否指向哪个对象。


在解决RHS时: foo = {n:2} ; 现在foo指的是{n:2};


回到我们剩下的问题:


foo.x = foo;


现在,LHS上的foo.x仍然是{n:1} .x,而RHS上的foo是{n:2}。


因此,在执行该语句后,{n:1}将变为{n:1,x:{n:2}},并且bar仍引用该语句。凡为FOO现在将参照{N:2} 。


因此,在执行foo.x时会给出undefined,因为foo中只有1个值为{n:2}的值。


但是,如果您尝试执行bar.x,它将得到{n:2}。或者,如果您只执行bar,结果将是


对象{n:1,x:对象}



查看完整回答
反对 回复 2019-12-14
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

我以为我会添加另一种我认为有用的思考方式。


最后的变量分配等同于write bar.x = foo = {n:2};,因为这些变量只是对内存中同一事物的引用。


换句话说,foo和bar首先都引用相同的对象{n:1}。使用时foo.x =,您正在访问{n:1}该x属性并将其添加到其中。这可以通过任一方法完成,bar或者foo因为它们都指向内存中的同一对象!这没什么区别。


然后,当您完成该行时,foo.x = foo = {n:2}您将通过对象文字语法在内存中创建另一个全新的对象,并设置foo为指向该对象{n:2},而不是现在的对象{n:1, x: {n: 2}。但是,这不会影响foo将x属性添加到该属性时所指向的内容。


这非常令人困惑,但是我认为您可以考虑这样一个事实,即变量只是指向内存中的位置/对象的指针,并且对象文字语法不会更改先前存在的对象(即使它们看起来很相似)。它正在创造一个全新的。



查看完整回答
反对 回复 2019-12-14
  • 3 回答
  • 0 关注
  • 338 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信