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

我在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};什么?


桃花长相依
浏览 339回答 3
3回答

暮色呼如

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})首先评估左侧,然后评估右侧。

LEATH

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:对象}

喵喵时光机

我以为我会添加另一种我认为有用的思考方式。最后的变量分配等同于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属性添加到该属性时所指向的内容。这非常令人困惑,但是我认为您可以考虑这样一个事实,即变量只是指向内存中的位置/对象的指针,并且对象文字语法不会更改先前存在的对象(即使它们看起来很相似)。它正在创造一个全新的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript