在学习JavaScript的时候遇到了自增和自减,不得不说JavaScript真是奇奇怪怪,整这........么一大堆的加号,怎么看起来这么让人头大,不过还是要学呀 ♂️,话不多说,继续上干货 !!!!
a++与++a
在讲标题的一堆加号之前的,我们先弄清楚js里自增这个概念。别看它加号这么多,但依然是一元运算符中的一员。
引用网道里的解释
a++/--:放在变量之后的自加或者自减运算符,会先返回变量操作前的值,再进行自增/自减操作;
通俗来讲就是,++是一个很自私的人,你都给他整到变量后边去了,明显就是瞧不起他,那它就先把它自己本来的数返回给你,然后自己再偷摸加个1。
--/++a:放在变量之前,会先进行自增/自减操作,再返回变量操作后的值。
放在变量之前的呢就比较开心了,你对我进行了这种操作,那我很识相的麻溜返回给你一个加1的数。
举个栗子 :
let x = 3
let y = x++
console.log(y)
输出几呢?显而易见当然是3。 给x赋值为3,给y赋值为x++,变量后的++小气的很,所以把3返回并赋值给y,最后x = 4 ,y = 3
let x = 3
let y = ++x
console.log(y)
输出几呢?给x赋值为3,给y赋值为x++,变量前的++大气,自增1后赋值给y,所以最后x = 4 ,y = 4
相信大家看到这里已经对a++与++a有了一个很直观的了解,那么回归正题
a+++a与a+a++
学过上边的同学站起来抢答,这个我知道
a+++a按照运算优先级就是(a++)+a,形式上完全等同于a+a++,所以这两个相等
然后自信满满的写了代码去验证
let a = 1
console.log( a+++a )
let a = 1
console.log( a+a++)
结果发现例1输出3,例2输出2
难道前边的都讲错了吗?当然没有,这就跟js的编译原理有关了
+
/ \ / \ a a++
编译器的处理过程:\
- push(a), a入栈(1)\
- push(a++),即push(1),之后 a自增变成2\
- result = pop()+pop(), 出栈两个操作数(1,1)相加,得到2
+
/ \ / \ a++ a
编译器的处理过程:\- push(a++), 即push(1),之后 a自增变成2\
- push(a),即push(2)\
- result = pop()+pop(), 出栈两个操作数(1,2)相加,得到3
所以才有了这个结果
简单来讲
- 对于a+++a,先传入前边的,又变量后的++优先级比较高,所以先传入了一个整体(a++),然后进行计算,小气的++返回本来的数值1,之后自增变为2,这时再传入a,这时的a还在外边,它感谢++的给力,然后摇身一变,有了一个值2。最后执行加法,结果为3
- 对于a+a++,我先传入前边的a,这时他的数值为1,然后我再传入整体a++,同理,小气的++也是返回本来的数值1,自增为2,但已经没人care它有没有自增了,因为大家都已经进去了,所以最后执行加法就是2
案例引用自若愚老师
\
补充一下
涉及到了一些关于引用类型的知识
function incObj(obj){
return obj.n++
}
var o = {n:11}
console.log(o) //{n:11}
console.log(incObj(o)) //11 返回值是自身 但是已经完成了自增1,所以此时n其实已经是12了
console.log(o) //12
然后
function incObj(obj){
return ++obj.n
}
var o = {n:11}
console.log(o) //{n:11}
console.log(incObj(o)) //12 返回值就已经加1了
最后
function incObj(obj){
return obj.n++
}
var o = {n:11}
let a = incObj(o) //执行函数之后,返回值是11,但n已经自增为12了
console.log(o) //{n:12}
console.log(a) //11
/*这就可以很好的解释a++与++a的区别,虽然二者最终实现的结果都是自增1,但是++a返回值是加1的,而a++的返回值仍然是他本身*/