AND和OR运算符都可以进行快捷方式处理。
因此,&&
仅在第一个表达式为true(类似于真值)时才尝试执行第二个表达式。第二个操作执行的内容(foo()
包含的任何内容)并不重要,因为除非第一个表达式评估为真值,否则它不会被执行。如果它是真值,则将执行它以尝试第二个测试。
相反,在||
语句中第一个表达式为true时,第二个表达式不会被触发。这是因为整个语句已经可以被评估,无论第二个表达式的结果如何,该语句的结果都将为true,因此第二个表达式将被忽略并保持未执行状态。
当使用此类快捷方式时要注意的情况,当定义变量仍然评估为falsy值(例如0
)和truthy值(例如'zero'
)时。
这被称为短路求值。
在这种情况下,如果x
是False,则不需要评估foo()
(&&
的结果始终为False);如果x
是True,则需要评估它(即使结果被丢弃)。
这两者并不完全等价。第一个是一个带有返回值的表达式,你可以使用它;而第二个是一个语句。
如果你对返回值不感兴趣(也就是说,不关心x
和foo()
是否都为真值),那么它们是等价的,但通常情况下,只有在你想将其作为布尔表达式使用时才应该使用布尔逻辑版本,例如:
if (x && foo()) {
do_stuff();
}
foo()
感兴趣(当x为truthy时),则更建议使用第二种形式,因为它更清晰地传达了意图。&&
运算符从左到右进行评估,并返回最右侧操作的值。如果第一个条件评估为false,则不会评估第二个条件。因此,它是一种简写形式,表示“如果某些东西不是null或undefined,则执行某些操作”。它短路了。
&&
运算符的工作原理:对两个操作数进行逻辑或运算。如果左边的操作数为非零值,则右边的操作数会进行求值以确定真值。如果左边的操作数为零,则无论右边的操作数是什么,表达式都将求值为 0,因此右边的操作数不会被求值。x
非零时,只有 foo
会被调用;x
为 0 时,foo
不会被调用,因此在这种情况下,它的工作方式类似于 if - else
。
if(x){foo();}
或者if(x) foo();
的可读性几乎是一样的,但后者更加普遍。 - Kzqaiif( x && foo() ) { ... }
混淆,后者是可以接受的并且具有不同的含义。就我个人而言,我不介意使用x && foo()
,特别是如果这种语法在很多情况下都会出现......JS 受益于最小化处理。 - vol7ronwindow.console && console.log('xyz');
,它可以避免在没有启用控制台的浏览器中出现错误日志命令。请注意,这句话的意思是在条件为真时才执行打印命令,防止出现未定义的情况。 - bbg