一行中的两个作业
Two assignments in one line
假设我们从这个开始:
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}
当一行中有多个赋值时,有人可以为我说明操作顺序吗?
此外,将上述情况与以下情况区分开来的基本规则是什么:
Multiple variable assignments in one row
上述问题中的一些答案声称基元的赋值是从右到左执行的...
赋值从右到左,但赋值目标求值是从左到右。
基本上整个表达式从左到右开始计算,但实际赋值需要从右侧开始计算 return 值。所以分配本身必须在重新调整右侧的评估值之后发生。
作业确实是从右到左进行的。只是 foo.x
的解析发生在赋值之前。 (Ecma Standard 11.13.1 Simple Assignment)
这样想。在赋值之前,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
}
假设我们从这个开始:
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}
当一行中有多个赋值时,有人可以为我说明操作顺序吗?
此外,将上述情况与以下情况区分开来的基本规则是什么: Multiple variable assignments in one row
上述问题中的一些答案声称基元的赋值是从右到左执行的...
赋值从右到左,但赋值目标求值是从左到右。
基本上整个表达式从左到右开始计算,但实际赋值需要从右侧开始计算 return 值。所以分配本身必须在重新调整右侧的评估值之后发生。
作业确实是从右到左进行的。只是 foo.x
的解析发生在赋值之前。 (Ecma Standard 11.13.1 Simple Assignment)
这样想。在赋值之前,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
}