JavaScript代码技巧:什么';s是foo.x的值
我在GitHub前端面试问题集合中发现了这个问题: 问题:foo.x的价值是什么 答案是JavaScript代码技巧:什么';s是foo.x的值,javascript,object,variable-assignment,Javascript,Object,Variable Assignment,我在GitHub前端面试问题集合中发现了这个问题: 问题:foo.x的价值是什么 答案是未定义 我做了一些研究,我理解这个问题是(如果我错了,请纠正我): var foo={n:1}声明一个对象foo,其属性n等于1 var bar=foo声明一个对象bar,该对象引用与foo相同的对象 foo.x=foo={n:2}对象的属性x 重要的是,foo.x引用的foo是在foo更改之前确定的 见: 让lref作为计算LeftHandSideExpression的结果 设rref为赋值表达式求值的结
未定义
我做了一些研究,我理解这个问题是(如果我错了,请纠正我):
声明一个对象var foo={n:1}
,其属性foo
等于1n
声明一个对象var bar=foo
,该对象引用与bar
相同的对象foo
foo.x=foo={n:2}我相信它等于
foo.x=(foo={n:2})代码>
- 然后我得到
等于foo.x
。但是,undefined
的值是对象bar.x
{n:2}
bar
和foo
引用同一个对象,为什么bar.x
在foo.x
未定义的情况下获取一个值?在foo.x=foo={n:2}中真正发生的事情代码>
foo.x = foo = {n: 2};
确定foo.x
引用{n:1}
对象的属性x
,将{n:2}
赋值给foo
,并将foo
-{n:2}
的新值赋值给{n:1}/code>对象的属性x
重要的是,foo.x
引用的foo
是在foo
更改之前确定的
见:
让lref作为计算LeftHandSideExpression的结果
设rref为赋值表达式求值的结果
赋值运算符从右向左关联,因此您可以得到:
foo.x = (foo = {n: 2})
左侧在右侧之前进行评估
foo.x = foo = {n: 2};
这里foo
指赋值前,即执行语句前的{n:1}
对象
语句可以重新写入为foo.x=(foo={n:2})代码>
在对象术语中,上述语句可以重写为
{n:1}.x=({n:1}={n:2})代码>
因为赋值只能从右向左进行。所以这里我们只需要在执行开始之前检查foo
是否引用了哪个对象
关于求解R.H.S:foo={n:2}
现在foo
指的是{n:2}代码>
回到留给我们的问题上:
foo.x = foo;
现在L.H.S上的foo.x
仍然是{n:1}.x
,而R.H.S上的foo
是{n:2}
因此,在执行此语句之后,{n:1}
将变成{n:1,x:{n:2}
,而bar仍然引用它。
其中asfoo
现在指的是{n:2}
因此执行foo.x
时会给出未定义的,因为foo
中只有一个值,即{n:2}
但是如果您尝试执行bar.x
,它将给出{n:2}
。
或者,如果只执行bar
,结果将是
Object {n: 1, x: Object}
我想我应该加上另一个,我发现的,有助于思考这个问题的方式
这些最后的变量赋值相当于写入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}
。但是,这并不影响将x
属性添加到它时foo
指向的内容
这是相当令人困惑的,但我认为有必要考虑这样一个事实:变量只是指向内存中的位置/对象的指针,而对象文字语法并没有改变以前存在的对象(即使它们看起来很相似),而是创建了一个全新的对象
接受答案的开头可能也会有帮助。需要理解的是,对象变量只是JavaScript中对象的引用,而不是对象本身
var foo={n:1}
->foo指的是真实对象{n:1}
var bar=foo
->bar现在也是对真实对象{n:1}的引用
棘手的部分当然是第三行:
foo.x=foo={n:2}
这相当于:
(对{n:1}的引用).x=(foo={n:2})
->在这一行完全求值后,foo成为对新对象{n:2}的引用;但是,由于foo在求值该行之前引用原始对象{n:1}
,原始对象{n:1}
变成{n:1,x:[引用]{n:2}
行求值后,修改后的对象将通过参考栏
访问。如果没有参考栏,原始对象将被销毁,正如我所理解的表达式:
foo.x = foo = {n: 2};
完全一样:
foo.x = {n: 2} ;
foo = {n: 2};
在这之后,很明显:
bar=={n: 1, x: {n:2}};
foo=={n:2};
foo.x==undefined
我认为在Javascript中,如果对象不是空的,就不能为不存在的属性赋值。因此,在本例中,foo对象有一个属性和值对,即{n:1}因此,因为它不是空的,它没有X属性,所以不能赋值,但是因为您将条形码对象指定为FO对象的值,所以无论FoO是它都将具有值,而在面试中这样的问题是可怕的……我会认为这是一个错误。
bar=={n: 1, x: {n:2}};
foo=={n:2};
foo.x==undefined