var a = 0
console.log(a || 1 && a++);
console.log(a)
var a = 0
console.log(a || 1 && ++a);
console.log(0 && "foo" + 5);
结果:
0
1
1
0
这里的规律像是从左向右执行,按理说&&先执行的话a就会先变成1,那么第一行该输出1,比较矛盾.为什么会这样?
var a = 0
console.log(a || 1 && a++);
console.log(a)
var a = 0
console.log(a || 1 && ++a);
console.log(0 && "foo" + 5);
结果:
0
1
1
0
这里的规律像是从左向右执行,按理说&&先执行的话a就会先变成1,那么第一行该输出1,比较矛盾.为什么会这样?
运算符优先级 看这个文档,优先级表里罗列的情况,逻辑与(&&)高于逻辑或(||)。
逻辑或(||)总结:
只要第一个值的布尔值为false,那么永远返回第二个值。
逻辑或属于短路操作,第一个值为true时,不再操作第二个值,且返回第一个值。逻辑与(&&)总结:
只要第一个值的布尔值为true,那么永远返回第二个值。
逻辑与属于短路操作,第一个值为false时,不再操作第二个值,且返回第一个值。作者:Rin阳
链接:https://www.jianshu.com/p/07a...
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
明白了这个逻辑之后,再看:
var a = 0
console.log(a || 1 && a++);
console.log(a)
先看第一段,a = 0时,先看与运算console.log(1 && a++) ,此时涉及到了自增 (++), 这里 a++ 是后置自增,操作数将在自增前返回,实际上是console.log(1 && 0) ,打印结果当然是0,那么,0 || 0 返回的是0,然后第一行的打印就是0;然后a自增后返回的a是1,所以console.log(a)打印结果当然是1;
var a = 0
console.log(a || 1 && ++a);
console.log(0 && "foo" + 5);
再看第二段,a = 0时,还是先看与运算console.log(1 && ++a) ,跟第一段不同的是 这里 ++a 是前置自增,操作数将先自增后返回,实际上是console.log(1 && 1) ,打印结果当然是1,那么,再看 a || 1 返回的依然是1,然后第一行的打印就是1;
然后console.log(0 && "foo" + 5) 打印结果当然是0,因为是一个非真值在前,进行&&操作。
他其实就是一个从左到右执行
a || 1 && a++
这个首先判断了 a
, 因为 a == 0
, 所以执行 ||
右边内容 1 && a++
++
在表达式右侧, 先取值再++
, 所以表达式是 1 && 0
, 右侧的值执行后为 0
那么他的完整式子就是
a || 1 && a++
0 || 1 && 0
0 || 0
0
a || 1 && ++a
整个执行过程和上一个几乎一样, 除了在++
的处理上, 因为这个式子的 ++
在左侧, 所以先+1
再取值, 整个式子就变成了
a || 1 && ++a
0 || 1 && 1
0 || 1
1
0 && "foo" + 5
这个就简单多了, 因为是 &&
操作, 所以当左侧的值为 false
时, 直接返回, 不执行右侧, 所以不管右边写什么都直接返回 0
其实上面那两个式子想要证明从左到右执行很简单, 你把或号左侧的值改成 1
, 右边你写什么它都会返回是 1
了
10 回答11.1k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
&&
的确是先执行的,但是计算机算法是基于栈的计算方式;也就是计算机首先要将整个算式一个一个的扫描入栈,然后才能通过优先级来进行计算。
当他扫描到第一个是变量的时候,就会把他当前的值入栈,因此虽然
&&
做完之后a = 1
但是,在扫描入栈的时候a = 0
, 也就是栈内所存的还是 0 ,因此最终表达式应该是0 || 1 && 0
;下面有个更好理解的:
很明显
*
肯定是优先执行的,第一个算式讲道理应该结果是1
, 但运行结果确是0
,原因就是在扫描算式入栈的时候 先扫描到a
,而a
当时等于0
, 等到计算完a++
的时候,虽然a
等于了1
, 可是之前入栈的0
是不会变成1
的,因为计算机根本不知道这个0
是之前的a
!但是第二次计算由于
a++
在前面,因此入栈的时候先计算了a++
, 虽然入栈的时候 是0
但a
已经等于1
了。PS:
在
||
左边为1
的情况下,计算机或主动跳过右侧
计算,并终止扫描,原因就是||
的优先级比较低,因此最终一定会执行||
,而1 || *
都等于 1;