JavaScript三元运算符和赋值

30

我在这个简单的JavaScript赋值语句中得到了意外的结果:

var t = 1 == 1 ? 1 : 0;
undefined

我本来期望t被赋值为1。如果您执行以下操作,结果相同。
var t = (1 == 1 ? 1 : 0);
undefined

有人能解释一下为什么这个没有按预期工作吗?

8
你是在控制台里面进行操作吗?如果是的话,只需要在赋值代码后面输入 t 就可以查看 t 实际上的值。我知道 WebKit 控制台是这样工作的。 - Matt Ball
1
这与运算符无关,而与不理解调试器的工作方式有关。 - epascarello
4个回答

31
在Firebug控制台中运行var t = 1 == 1 ? 1 : 0;,结果会显示undefined。但是,t的值将如预期一样为1。尝试在赋值后输出t
如果变量声明位于单独的一行,Firebug将打印出结果。
var t;
t = 1 == 1 ? 1 : 0;

这是因为赋值操作的返回值是被赋的值。但是,当有var关键字时,返回的是VariableStatement声明的值,其行为如下:

产生式VariableStatementvar VariableDeclarationList; 的评估结果如下:评估 VariableDeclarationList。返回(normal,empty,empty)。

其中返回(normal,empty,empty)是JavaScript内部识别的一种类型,而不是会打印到控制台上的内容。
进一步阅读:

http://ecma262-5.com/ELS5_HTML.htm#Section_12.2


17

它完美地工作:

> var t = 1 == 1 ? 1 : 0;
undefined
> t
1

你可以说赋值操作的返回值是undefined,而不是t的值。

编辑:但实际上,如果我正确地阅读了规范文档,它似乎应该返回表达式的值。

正如@T.J.Crowder提到的那样,似乎是var导致了undefined的值。但这并不意味着你不应该使用var。你编写的代码是100%正确的。

这更深入地涉及语言的内部工作,我认为这不是你感兴趣的内容。但是,如果需要更多信息,请查看评论。


3
实际上,“赋值操作”的值是被赋的值。然而,在控制台中,关键字“var”似乎有些妨碍。由于“var”不能出现在表达式的右侧,所以这并不让我感到惊讶;这似乎是处理控制台方面的有效方法。 - T.J. Crowder
1
@TJCrowder:没错,似乎是var的问题。感谢您的见解。 - Felix Kling
2
发生的情况是var语句返回一个没有值的正常完成赋值操作的值显然是被赋值表达式的值,例如:var a; alert(a = 'foo'); alert(a);将会两次弹出'foo'... 一段时间以前我正在写一篇关于完成类型的文章,但我还没有时间完成它,这里是一个旧的草稿 - Christian C. Salvadó
@TJCrowder, @CMS:我刚刚查看了规范的这一部分,上面写着评估返回(normal, empty, empty),所以我猜这就是你所说的“正常完成”(在查看你的草稿后我可以确认)。谢谢! - Felix Kling
@CMS:再次注意到,我不应该过多地谈论我没有完全了解的事情 ;) - Felix Kling
@CMS:我刚刚在阅读规范并回复了一个类似的答案。对我来说,“Return (normal, empty, empty)”明显是指某种内部返回类型,但我不熟悉这个术语。谢谢你的解释。 - Wayne

4
在旧的JavaScript解析器中,我们需要将条件放在括号中进行结论:
var t = (1 == 1) ? 1 : 0;

6
自1996年起,我一直在浏览器实现中使用JavaScript。我从未见过其中一个运算符的优先级出错。你有相关资料吗? - T.J. Crowder

1

这段代码运行良好:

var t = 1 == 1 ? 1 : 0;
alert (t);

在这里 检查。它显示 1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接