JavaScript有“短路”评估吗?
我想知道JavaScript是否有像C#中的&&Operator那样的“短路”评估。如果没有,我想知道是否有一种可行的解决方法可以采用。
我想知道JavaScript是否有像C#中的&&Operator那样的“短路”评估。如果没有,我想知道是否有一种可行的解决方法可以采用。
这个答案详细介绍了短路在JavaScript中的工作原理,包括所有陷阱以及运算符优先级等相关主题,如果您正在寻找一个快速定义并且已经了解短路的工作原理,我建议您检查其他答案。
首先,让我们检查一下我们都熟悉的行为,在块内,我们用来检查这两件事是否是:if()
&&
true
if (true && true) {
console.log('bar');
}
现在,你的第一个直觉可能是说:“啊,是的,很简单,如果expr1
和expr2
都被评估为真
,代码就会执行语句。
好吧,是和不是。从技术上讲,你是对的,这就是你描述的行为,但这并不是评估代码的确切方式,我们需要深入研究才能完全理解。
&&
||
现在是时候看看“在javascript引擎的引擎盖下”。让我们考虑一下这个实际的例子:
function sanitise(x) {
if (isNaN(x)) {
return NaN;
}
return x;
}
let userinput = 0xFF; // as an example
const res = sanitise(userinput) && userinput + 5
console.log(res);
好吧,结果是..但是为什么?为了得到答案,我们需要了解短路评估是如何工作的。260
根据MDN定义,运算符按以下方式执行:
&&
expr1 && expr2
如果可以转换为 ,则返回 ;否则,返回 。
expr1
true
expr2
expr1
因此,这意味着,在我们的实际示例中,按以下方式评估:const res
expr1
- sanitise(0xFF)
0xFF
是 250 的有效十六进制数,否则我会返回NaN
,因为NaN
是假的)expr1
expr2
userinput
+5
因此,在这里,我们能够通过运算符的简单使用来避免额外的块和进一步的检查。if
isNaN
&&
到现在为止,我们至少应该了解短路算子是如何工作的。普遍规则是:
(一些虚假的表达)&&expr
将评估为虚假的表达(一些真话表达式)|| expr
将计算为真话表达式以下是一些更好的理解示例:
function a() { console.log('a'); return false; }
function b() { console.log('b'); return true; }
if ( a() && b() ){
console.log('foobar');
}
//Evaluates a() as false, stops execution.
function a() { console.log('a'); return false; }
function b() { console.log('b'); return true; }
if ( a() || b() ){
console.log('foobar');
}
/* 1. Evaluates a() as false
2. So it should execute expr2, which is `b()`
3. b() returned as true, executing statement `console.log('foobar');`
*/
很好,希望你能掌握它的窍门!我们需要知道的最后一件事是关于运算符优先级的规则,即:
&&
运算符始终在||
运算符之前执行。请考虑以下示例:
function a() { console.log('a'); return true;}
function b() { console.log('b'); return false;}
function c() { console.log('c'); return false;}
console.log(a() || b() && c());
// returns a() and stops execution
这将返回为,也许令人困惑的是某些人作为。理性很简单,只是我们的视力在欺骗我们,因为我们习惯于从左到右阅读。让我们把和没有的东西拿出来,纯粹专注于评估a()
console.log()
true || false && false
现在来解决这个问题:
我们说运算符具有优先级,因此它被评估为第一个。为了帮助我们更好地想象评估,想想定义&&
expr1 && expr2
哪里:
expr2
是false
expr1
是true || false
所以这是棘手的部分,现在被评估(- 左侧)。true || false
expr1
&&
||
expr1 || expr2
expr1
expr1
返回值为true
井。。这是非常棘手的,这一切都是因为很少有奇怪的规则和语义。但请记住,您始终可以使用 - 就像在数学中一样,可以逃避运算符的优先级()
function a() { console.log('a'); return true;}
function b() { console.log('b'); return false;}
function c() { console.log('c'); return false;}
console.log((a() || b()) && c());
/* 1. The () escape && operator precedence
2. a() is evaluated as false, so expr2 (c()) to be executed
3. c()
*/