假设我们从此开始:
var foo = {n:1};
var bar = foo;
在JavaScript中,执行以下任务的顺序是什么:
foo.x = foo = {n:2};
当我查找此答案时,我发现有几个似乎暗示分配从右到左进行,例如:
foo = {n:2};
foo.x = foo;
在这种情况下,我们会期望:
console.log(foo) //{n:2, x:Object} - (a circular reference back to foo)
然而,当我实际执行此操作时,我在控制台中看到的表明,作业实际上是从左到右发生的:
console.log(foo) //{n:2}
console.log(bar) //{n:1, x:Object}
-> {n:1} obj获取'x'属性,然后将foo重新分配到新对象{n:2}
当一行有多个作业时,有人可以为我澄清操作顺序吗?
另外,将上述情况与以下情况区分开的基本规则是什么:一行多变量分配
上述问题中的某些答案声称原始词的作业是右至左进行的...
分配确实从右到左。只是foo.x
的分辨率发生在分配之前。(ECMA标准11.13.1简单分配)
这样想。在分配之前,foo
和bar
恰好指向内存中的相同对象。(我们将其称为inMemoryObject
)。
foo --|
bar --|
|---> inMemoryObject {
n:1
}
然后,我们在分配方法开头参考foo.x
。由于foo.x
不存在,因此占位符会创建,准备分配给。
foo --|
bar --|
|---> inMemoryObject {
n:1,
x: undefined
}
创建了变量后,就开始左右分配过程,分配给inMemoryObject.x
。在分配过程结束时,foo
不再指向inMemoryObject
,但bar
仍然可以。
bar --|
|---> inMemoryObject {
n:1,
x: --|
foo --| } |
| |
|----------------------------|--- secondInMemoryObject {
n:2
}
作业从右到左进行,但是分配目标评估是从左到右进行的。
基本上,整个表达式从左到右开始评估,但是实际分配需要从右侧的返回值。因此,在重新调整右侧评估价值之后,必须发生评估本身。