”现实“的++之a+++a与a+a++

442 阅读3分钟

在学习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++

编译器的处理过程:\

  1. push(a), a入栈(1)\
  2. push(a++),即push(1),之后 a自增变成2\
  3. result = pop()+pop(), 出栈两个操作数(1,1)相加,得到2

    +
    / \ / \ a++ a

    编译器的处理过程:\
  4. push(a++), 即push(1),之后 a自增变成2\
  5. push(a),即push(2)\
  6. 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++的返回值仍然是他本身*/