11-短路求值
5.8.1 短路求值
如果仔细看与的真假表(表5-2),会发现有一个快捷判断方式:如果x是false,不管y的值是什么,结果都为false。同样,对于 x || y ,一旦x是true,就不用再计算y的值了。JavaScript也确实是这么做的,这种方式叫短路求值。
为什么短路求值如此重要呢?因为如果第二个操作数有副作用,短路后程序就不会执行它们了。一般来说,“副作用”在程序中是一件坏事,但它也并非总是这样:如果副作用是故意引入的,并且用法很清楚,那么它就不再是件坏事了。
在表达式中,自增、自减、赋值,以及函数调用都可以引发副作用。前文已经讲解了自增和自减运算符,来看一个例子:
const skipIt = true;
let x = 0;
const result = skipIt || x++;
例子中的第二行代码会直接将值存储在变量 result 中。因为第一个操作数( skipIt )是 true ,所以result的值为 true 。然而,有趣的是,由于短路求值,自增表达式没有执行,所以x的值还是 0 。如果将 skipIt 改成 false ,那么两个表达式都会被执行,所以自增表达式也会被执行。在这里,自增就是副作用。同样的事情也会发生在与运算符中:
const doIt = false;
let x = 0;
const result = doIt && x++;
同理,JavaScript不会解析第二个包含自增表达式的操作数。因为第一个操作数为 false ,执行到这里会被短路,所以 result 的值为 false , x 的值也没有变。如果把 doIt 的值改为 true 会发生什么呢?此时JavaScript会解析两个操作数,所以自增也会执行,而 result 的值变成了 0 。等等,什么? result 为什么是 0 而不是 false ?这个问题的答案将巧妙地把我们带入下一个主题。