“x && foo()”是什么?

46

我在其他地方看到过这样的说法:

x && foo();

等同于

if(x){
    foo();
}

我测试过,它们确实做了同样的事情。
但是为什么?x && foo()到底是什么意思?


30
虽然这是一个巧妙的技巧,但我希望你不要使用它。它确实有效,但被认为是不好的行为方式。 - Charles Caldwell
4
我同意@PortableWorld的观点。在一行中使用if(x){foo();}或者if(x) foo();的可读性几乎是一样的,但后者更加普遍。 - Kzqai
4
但请注意不要将此与 if( x && foo() ) { ... } 混淆,后者是可以接受的并且具有不同的含义。就我个人而言,我不介意使用 x && foo(),特别是如果这种语法在很多情况下都会出现......JS 受益于最小化处理。 - vol7ron
11
这个成语的一个好用法是 window.console && console.log('xyz');,它可以避免在没有启用控制台的浏览器中出现错误日志命令。请注意,这句话的意思是在条件为真时才执行打印命令,防止出现未定义的情况。 - bbg
10
我认为这很美丽。 - NullUserException
显示剩余5条评论
5个回答

70

AND和OR运算符都可以进行快捷方式处理。

因此,&&仅在第一个表达式为true(类似于真值)时才尝试执行第二个表达式。第二个操作执行的内容(foo()包含的任何内容)并不重要,因为除非第一个表达式评估为真值,否则它不会被执行。如果它是真值,则将执行它以尝试第二个测试。

相反,在||语句中第一个表达式为true时,第二个表达式不会被触发。这是因为整个语句已经可以被评估,无论第二个表达式的结果如何,该语句的结果都将为true,因此第二个表达式将被忽略并保持未执行状态。

当使用此类快捷方式时要注意的情况,当定义变量仍然评估为falsy值(例如0)和truthy值(例如'zero')时。


4
请查阅你所使用的编程语言的语法规范,确保它遵循相同的快捷执行终止规则。存在一些违反这一规则的旧版编程语言。 - John Tobler
实际上,在Delphi中,您可以为整个项目、特定文件甚至某个函数周围关闭它。疯狂的东西 :) http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsbooleanshortcircuitevaluation_xml.html - Davy Landman
5
@John:这个问题明确提到JavaScript... - Donal Fellows

25

这被称为短路求值

在这种情况下,如果x是False,则不需要评估foo()&&的结果始终为False);如果x是True,则需要评估它(即使结果被丢弃)。


啊,维基百科的文章确实覆盖了一切。像往常一样。 - Kzqai
4
如果你知道该看什么,它确实会有所不同! - johnsyweb

8

这两者并不完全等价。第一个是一个带有返回值的表达式,你可以使用它;而第二个是一个语句。

如果你对返回值不感兴趣(也就是说,不关心xfoo()是否都为真值),那么它们是等价的,但通常情况下,只有在你想将其作为布尔表达式使用时才应该使用布尔逻辑版本,例如:

if (x && foo()) {
    do_stuff();
}

如果您只对有条件运行foo()感兴趣(当x为truthy时),则更建议使用第二种形式,因为它更清晰地传达了意图。
人们可能更喜欢布尔逻辑版本的原因是,JavaScript受到一项不寻常的限制:源代码大小(更冗长的源代码意味着使用更多带宽);由于布尔逻辑版本使用的字符较少,因此更节省带宽。大多数情况下,我仍然更喜欢更冗长的版本,除非涉及的脚本经常使用 - 对于像jQuery这样的库,使用这样的优化是完全合理的,但在大多数其他情况下则不合适。

3
在JavaScript中,&&运算符从左到右进行评估,并返回最右侧操作的值。如果第一个条件评估为false,则不会评估第二个条件。因此,它是一种简写形式,表示“如果某些东西不是null或undefined,则执行某些操作”。

2

它短路了。

&& 运算符的工作原理:对两个操作数进行逻辑或运算。如果左边的操作数为非零值,则右边的操作数会进行求值以确定真值。如果左边的操作数为零,则无论右边的操作数是什么,表达式都将求值为 0,因此右边的操作数不会被求值。x 非零时,只有 foo 会被调用;x 为 0 时,foo 不会被调用,因此在这种情况下,它的工作方式类似于 if - else


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