前面介绍了基本的算术运算符,由于自增和自减运算符在面试中考察相对复杂,所以这里单独拿出来介绍。
自增和自减运算符用法非常简单,自增运算符就是让这个变量加一,自减运算符就是让这个变量减一,用下面的代码就能理解
js
var a = 1;
a++;//相当于a = a + 1
console.log(a);//2
a--;//相当于a = a - 1
conosle.log(a);//1自增和自减运算符既可以写在变量前面,也可以写在变量后面。
js
var a = 1;
++a;
console.log(a);//2
a++;
console.log(a);//3
a--;
console.log(a);//2
--a;
console.log(a);//1前置和后置的自增自减从功能上来说是一样的,但在取值操作的时候有一点区别,或者说表达式的值不太一样,前置自增/自减运算符的值为执行运算之后的值,而后置自增/自减运算符的值为执行运算之前的值。
js
var a = 1;
console.log(a++);//1,也就是执行++之前的值
console.log(a);//2
//此时a为2
console.log(++a);//3,也就是执行++之后的值
console.log(a);//3
//此时a为3
console.log(--a);//2,也就是执行--之后的值
console.log(a);//2
console.log(a--);//2,也就是执行--之前的值
console.log(a);//1这里可能会遇到一些非常恶心的面试题,例如 x++ + 1,比如 ++x + 1,比如 ++x + y--
这里给出我个人对这种题的解法和理解,前置自增/自减运算符,既然运算符是放在数字前面,那就是先执行自增/减,再取值。后置自增/自减运算符,既然运算符在变量后面,那就先取值,再自增/减。
读者可以这样理解
js
var b = a++;
//这个代码等价于
var b = a;
a = a + 1;
var b = --a;
//这个代码等价于
a = a - 1;
var b = a;能看懂吧,如果一个语句中出现了自增和自减运算符,如果是前置的,相当于是在这条语句之前执行自增或自减操作,如果是后置的,相当于是在这条语句之后执行自增或自减操作,那些恶心的面试题就有了答案了。
js
var x = 1;
var y = x++ + 1;
console.log(y);//2根据前面说的规则,上面的代码等价于
js
var x = 1;
var y = x + 1;
x = x + 1;
console.log(y);运算符的优先级
这里可能有读者会有疑问,比如为什么 JS 中也是先算乘除后算加减,为什么 y = x + 1 这条语句为什么是先算 x+1,再执行 =,这都涉及到优先级的问题,所谓的优先级,就是当出现多个符号的时候优先级高的运算符会先进行计算,优先级的问题读者并不需要过多关心,我们只需要知道括号可以改变优先级即可,对于可能有歧义的地方,我们都可以使用括号强制改变其优先级即可,这样绝对不会出错。过度关心优先级,甚至把优先级背下来,这种学习方式只会徒增学习难度,对开发毫无帮助。
由于优先级对开发基本毫无帮助,关于优先级的具体规则,可以参考运算符优先级 - JavaScript | MDN
以上的方法只适用于一些不那么恶心的题,可能读者会看到一些非常恶心的题,如下
js
var x = 1;
var y = x + x++ + ++x;
console.log(y)我们也按照刚才的规则分析,题目中有一个后置自增和一个前置自增,所以分别会在这条语句之前和之后自增 1,上面的代码会等价成如下代码:
js
var x = 1;
x = x + 1;
var y = x + x + x;
x = x + 1;
console.log(y);//5这样的代码输出会是 6,但实际上结果是 5,如果要解释清楚这个题目,就要深入了解一下运算符的优先级。
- 从左到右依次运算
- 遇到操作数,将数据直接取出
- 除第一个运算符外,每遇到一个运算符,如果当前运算符优先级小于等于前一个运算符,则直接执行前一个运算符。
要计算 x + x++ + ++x,此时 x 是 1,从左到右依次看,首先,第一个 x 替换为 1,也就是 1+ x++ + ++x,此时 x 还是 1,然后读到+,这里继续读,然后读到 x++,显然,++ 优先级大于 +,所以继续往后看,看到下一个+的时候,此时 + 的优先级不如前面的 ++,所以会把前面的直接执行,也就是执行 x + x++,就变成了 2 + ++x,然后读到最后一个 ++x,此时由于 ++ 优先级高于 +,所以继续往后读,发现后面没有了,就直接执行 2+ ++x,最后的结果就是 5。
如果读者对这里不太能理解,建议去了解一下如何用两个栈进行中缀表达式的计算,这里其实是一样的。
我们可以这么理解,对于自增自减运算符,都是立刻执行,立刻改变变量的值,但是取值的时候,前置自增取的是改变之后的值,后置自增取的是改变之前的值。
通过这种方式分析可以解决 100%的面试题,但是这种题目是为了出题而出题,毫无实用价值,我们在正常开发中应该避免在一条语句中使用多个自增/减运算符这种奇葩的写法。