在同一指令中实例化两个变量时:
var foo = 1,
bar = foo + 1;
在V8中,这会产生foo == 1
和bar == 2
,
var bar = foo + 1,
foo = 1;
这会产生foo == 1
和bar == NaN
。
执行操作的顺序是否得到保证?或者单独声明foo
和bar
是否更安全?
var foo = 1;
var bar = foo + 1;
甚至
var foo, bar;
foo = 1;
bar = foo + 1;
答案 0 :(得分:3)
正如您已正确指出的那样,变量声明表达式将从左到右进行计算。将首先评估赋值的左侧,然后评估赋值表达式的右侧,然后进行赋值。
在第二种情况下,由于variable hoisting,您获得NaN
。当JavaScript看到
bar = foo + 1,
它将知道foo
在当前上下文中定义,但尚未分配值。因此,默认情况下,undefined
使用foo
。
console.log(undefined + 1);
# NaN
这就是为NaN
分配bar
的原因。
根据ECMA 5.1 Standard Docs' Variable Statement
section,变量声明将像这样评估
VariableStatement:
var VariableDeclarationList ;
VariableDeclarationList :
VariableDeclaration
VariableDeclarationList , VariableDeclaration*
这里,生产将像这样进行评估
生产 VariableDeclarationList:VariableDeclarationList,VariableDeclaration 的评估如下:
- 评估 VariableDeclarationList 。
- 评估 VariableDeclaration 。
醇>
因此,应该首先评估最左边的赋值表达式,而最后一个,最右边的一个。所以,你看到的行为是预期的行为。
答案 1 :(得分:2)
在同一指令中声明和初始化变量时,javascript会按照您期望的顺序执行操作。
例如,
var foo = 1,
bar = foo + 1;
完全有效,永远不会产生错误。另一方面
var bar = foo + 1,
foo = 1;
会产生bar === NaN
,就像你说的那样,因为首先发生的事情是bar会被初始化为foo + 1
,其中foo
在技术上是undefined
。< / p>
tl;博士是的。
答案 2 :(得分:1)
之间的区别
// Case 1
var foo = 1,
bar = foo + 1;
和
Case 2
var bar = foo + 1,
foo = 1;
是在第一种情况下,foo已经被定义为1,所以你的操作是1 + 1 在第二种情况下,当你定义bar时,foo仍然是未定义的。虽然已经宣布了。
在JS中,所有声明都将在程序运行之前发生。因此,即使您的所有var语句都位于代码的底部,它也可以工作。见这里:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting