JavaScript中的IF语句作为赋值表达式

4

JSLint错误解释文档(https://jslinterrors.com/unexpected-assignment-expression)指出,如果我们评估一个赋值表达式(x = 0),则IF语句体将永远不会被执行(y = 1)。

var x, y;
if (x = 0) {
    y = 1;
}

“if”语句的主体不会被执行,因为赋值表达式的结果是undefined,这是假值。但在“if(x = 1){y = 1;}”中,我可以证明相反的情况。这是JS版本的问题吗?
更新: 实际上,我犯了一个错误,认为可以将赋值结果用作测试值。我真正能够在控制台证明的是赋值返回一个值,例如x = 1输出1。

1
是的,这是错误的。这个赋值表达式不会导致未定义的结果。考虑在那个页面上留下评论。 - georg
2
哈哈,我们都在文章下面留言了。 :-) - T.J. Crowder
1个回答

4
那篇文章的摘录有些正确,但也有些是错误的。当使用 if (x = 0) 时,代码块不会被执行,这一点是正确的,但文章解释为什么会这样却是错误的。
错误的部分在这里:
代替检查变量 x 是否等于 0,上面的例子将会把值 0 赋给 x。if 语句体将不会被执行,因为赋值表达式结果为 undefined,而 undefined 是 falsy。
这完全是错误的。一个赋值表达式的结果是被赋的值本身,而不是 undefined,所以 if (x = 0) 不会进入 if 语句体(因为 0 是 falsy),但 if (x = 1) 会进入(因为 1 是 truthy)。
这与 JS 版本无关,这种情况一直存在。只是有些文档中出现了错误。
实际上,我们可以使用赋值表达式的结果作为测试值。有些情况下你需要这么做,这是相当常见的。
while ((thing = getMeTheNextThing()) != null) {
    // ...do something with `thing`
}

这也是使用分配结果作为测试的方式。有时人们甚至会像这样编写代码:

while (thing = getMeTheNextThing()) {
    // ...do something with `thing`
}

尽管我从来没有这么做过,因为很容易将其看作 == 并搞砸了一些东西。


请注意,在 if 语句中想要对变量进行赋值是非常非常罕见的情况。虽然确实会发生,但这种情况非常少,大多数风格指南都建议您拆分赋值和分支。

几乎总是当你看到 if (x = 0) 时,作者想写的是 if (x == 0) 或者 if (x === 0)。也就是说,他们想要测试x的值,而不是给x赋一个新值。

JSLint 文档关于赋值为零的示例:

var x;

snippet.log("first test: using 0");
if (x = 0) {
  snippet.log("entered if body");
} else {
  snippet.log("entered else body");
}

snippet.log("second test: using 1");
if (x = 1) {
  snippet.log("entered if body");
} else {
  snippet.log("entered else body");
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


1
@Crowder,你说得很到位,你的回答非常清晰!谢谢! - Igor de Lorenzi

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