JavaScript操作顺序
在同一条指令中实例化两个变量时:JavaScript操作顺序,javascript,Javascript,在同一条指令中实例化两个变量时: var foo = 1, bar = foo + 1; 在V8中,这将产生foo==1和bar==2 这将产生foo==1和bar==NaN 是否保证执行操作的顺序?或者单独申报foo和bar更安全 var foo = 1; var bar = foo + 1; 甚至 var foo, bar; foo = 1; bar = foo + 1; 正如您正确指出的,变量声明表达式将从左到右求值。首先计算赋值的左侧,然后计算赋值表达式的右侧,然后再赋值
var foo = 1,
bar = foo + 1;
在V8中,这将产生foo==1和bar==2
这将产生foo==1和bar==NaN
是否保证执行操作的顺序?或者单独申报foo和bar更安全
var foo = 1;
var bar = foo + 1;
甚至
var foo, bar;
foo = 1;
bar = foo + 1;
正如您正确指出的,变量声明表达式将从左到右求值。首先计算赋值的左侧,然后计算赋值表达式的右侧,然后再赋值 在第二种情况下,你得到了NaN,因为。当JavaScript看到
bar = foo + 1,
它将知道foo是在当前上下文中定义的,但尚未指定值。因此,默认情况下,它对foo使用undefined
这就是NaN被分配到bar的原因
根据,变量声明的计算方式如下
VariableStatement:
var VariableDeclarationList ;
VariableDeclarationList :
VariableDeclaration
VariableDeclarationList , VariableDeclaration*
在这里,生产将像这样进行评估
VariableStatement:
var VariableDeclarationList ;
VariableDeclarationList :
VariableDeclaration
VariableDeclarationList , VariableDeclaration*
生产VariableDeclarationList:VariableDeclarationList,VariableDeclaration的计算如下:
计算VariableDeclarationList。
计算变量声明。
因此,应该首先计算最左边的赋值表达式,最后只计算最右边的赋值表达式。因此,您看到的行为是预期的行为。正如您正确指出的,变量声明表达式将从左到右进行计算。首先计算赋值的左侧,然后计算赋值表达式的右侧,然后再赋值 在第二种情况下,你得到了NaN,因为。当JavaScript看到
bar = foo + 1,
它将知道foo是在当前上下文中定义的,但尚未指定值。因此,默认情况下,它对foo使用undefined
这就是NaN被分配到bar的原因
根据,变量声明的计算方式如下
VariableStatement:
var VariableDeclarationList ;
VariableDeclarationList :
VariableDeclaration
VariableDeclarationList , VariableDeclaration*
在这里,生产将像这样进行评估
VariableStatement:
var VariableDeclarationList ;
VariableDeclarationList :
VariableDeclaration
VariableDeclarationList , VariableDeclaration*
生产VariableDeclarationList:VariableDeclarationList,VariableDeclaration的计算如下:
计算VariableDeclarationList。
计算变量声明。
因此,应该首先计算最左边的赋值表达式,最后只计算最右边的赋值表达式。因此,您看到的行为就是预期的行为。在同一条指令中声明和初始化变量时,javascript会按照您预期的顺序执行操作 比如说,
var foo = 1,
bar = foo + 1;
是完全有效的,并且永远不会产生错误。另一方面
var bar = foo + 1,
foo = 1;
将产生bar==NaN,正如您所说的,因为首先会发生的事情是bar将被初始化为foo+1,其中foo在技术上是未定义的
tl;dr Yes。在同一条指令中声明和初始化变量时,javascript会按照您期望的顺序执行操作 比如说,
var foo = 1,
bar = foo + 1;
是完全有效的,并且永远不会产生错误。另一方面
var bar = foo + 1,
foo = 1;
将产生bar==NaN,正如您所说的,因为首先会发生的事情是bar将被初始化为foo+1,其中foo在技术上是未定义的
tl;医生:是的。两者之间的区别 //案例1 var foo=1, bar=foo+1 及 案例2 var bar=foo+1, foo=1 在第一种情况下,foo已经定义为1,因此您的操作是1+1 在第二种情况下,当您定义bar时,foo仍然是未定义的。虽然已经宣布了
在JS中,所有声明都将在程序运行之前进行。因此,即使您的所有var语句都位于代码的底部,它也可以工作。请参见此处:之间的区别 //案例1 var foo=1, bar=foo+1 及 案例2 var bar=foo+1, foo=1 在第一种情况下,foo已经定义为1,因此您的操作是1+1 在第二种情况下,当您定义bar时,foo仍然是未定义的。虽然已经宣布了
在JS中,所有声明都将在程序运行之前进行。因此,即使您的所有var语句都位于代码的底部,它也可以工作。请参见此处:这是有保证的。什么使你认为它不会呢?有些表达式是从右向左求值的。我想排除在V8以外的引擎中运行代码时遇到问题的可能性。我没有足够的知识来确定。@mingos有些表达式是从右到左求值的不,它们不是,它们总是从左到右求值。在var foo=1中,在运行任何代码之前,首先将foo创建为局部变量。然后在计算表达式foo=1时,首先计算foo并发现foo是一个局部变量,然后计算=表示赋值,然后计算右侧以查看将赋值。@RobG看一下这个答案:-虽然下面的注释不正确,但它表示不正确…@mingos如果帖子准确,未说明的Chrome版本不适用于
't,表示在计算左手边时,首先计算左手边。MacOS上的Chrome33与Safari和Firefox的行为相同,在这两种情况下都是从左到右。不过,这篇文章是3年前写的,所以现在Chrome可能已经兼容了-这是有保证的。什么使你认为它不会呢?有些表达式是从右向左求值的。我想排除在V8以外的引擎中运行代码时遇到问题的可能性。我没有足够的知识来确定。@mingos有些表达式是从右到左求值的不,它们不是,它们总是从左到右求值。在var foo=1中,在运行任何代码之前,首先将foo创建为局部变量。然后在计算表达式foo=1时,首先计算foo并发现foo是一个局部变量,然后计算=表示赋值,然后计算右侧以查看将赋值。@RobG看一下这个答案:-虽然下面的注释不正确,但它表示不正确…@mingos如果帖子准确,未说明的Chrome版本没有使用,这表示在评估左手侧时,首先评估左手侧。MacOS上的Chrome33与Safari和Firefox的行为相同,在这两种情况下都是从左到右。不过,这篇文章是3年前写的,所以现在Chrome可能已经兼容了-我理解NaN被分配的原因——这正是我希望发生的事情,真的。我想问的是,这种行为是否总是会发生——幸运的是,似乎是这样:。@RobG刚刚检查了规范,你是对的。谢谢:更新了答案。我理解为什么分配NaN-这正是我希望发生的事情,真的。我想问的是,这种行为是否总是会发生——幸运的是,似乎是这样:。@RobG刚刚检查了规范,你是对的。谢谢:更新了答案。在第二种情况下,在初始化bar时,foo实际上是未定义的,而不是NaN。在第二种情况下,在初始化bar时,foo实际上是未定义的,而不是NaN。