一、问题简述
在JavaScript中,存在着广泛且容易记错的问题,那就是:a+++a和a+a++的计算顺序,究竟是怎样的?
二、详细辨析
1.a+++a的实际运算顺序
首先让我们来回顾一下JavaScript中的运算符(操作符)优先级,下图是从MDN中截取的运算符优先级表,可以看出,“+”的优先级实际上是要低于“++”的。
然而“++”分为前置(++a)和后置(a++)两种,从表中可以看出,后置(a++)的优先级是要高于前置(++a)的,所以三者的优先级从高到低的排序应该是:"a++ > ++a > +"。
所以a+++a的运算顺序其实是等同于:(a++) +a 的,我们来实际测试一下这个结论:
可以从上图中看出,二者的运算结果是一致的,论证了我们的结论。
2.a+a++的实际运算顺序
通过上节我们列出的优先级表以及分析出的数据,可以看出,a++的优先级是高于+的,那么很容易得出这样一个结论,即:a+a++的实际运算顺序应该等同于:a+(a++),让我们继续来实际测试一下:
可以从上图中看出,二者的运算结果是一致的,事实又一次论证了我们的结论。
3.两者的差异
从a+++a和a+a++的实际运算结果不难看出,两者的运算结果并不一致,这是为什么呢?
虽然,两者的运算顺序都是,先运算a++,再+a,但是因为a++和+a/a+在表达式的位置不同,对运算结果产生了影响。
即:
+
/ \
/ \
a a++
编译器的处理过程:
1. push(a), a入栈(1)
2. push(a++),即push(1),之后 a自增变成2
3. result = pop()+pop(), 出栈两个操作数(1,1)相加,得到2
+
/ \
/ \
a++ a
编译器的处理过程:
1. push(a++), 即push(1),之后 a自增变成2
2. push(a),即push(2)
3. result = pop()+pop(), 出栈两个操作数(1,2)相加,得到3