i=i++;a=a++;后置递增递减运算符详解

问题

关于这段代码,如果有被迷惑过的同学,可能会很熟悉

let i = 0;
i = i++;
console.log(i);

结果输出为:0

关于 i=i++ 的问题,在百度上一搜一大堆,很多文章会直接通过汇编来看内存中是如何操作,还有一些是说这个问题,其实在早年是没有直接定义的,有些非常的老的编译器,可能会输出1,但是现在的编译器几乎不可能输出1,都是一样的结果为 0。这个问题早就不存在歧义了,只是在开发中几乎不会用到这种表达式。

解读

第二行代码 i = i++;

这行代码执行时,总共有二个步骤,先运算再赋值。运算这个步骤(i++)是一个后置递增运算符,那我们就先从这个后置递增运算符说起。

运算 i++ :
  • 首先 i 的原始数据复制一份放在一块内存中,我把这块内存叫做副本,i 的原始数据是0,那么副本的值就是0,然后原始数据开始递增0 + 1,那么就是1,注意这里,此时已经有两块内存存在了,并不是一块内存,原始数据占一块内存,而副本占一块内存,也就是说,原始数据那块内存的递增并不影响副本那块内存的值,好了,明白了这一点就好办了。
赋值 i = ?
  • 到赋值这个步骤了,此时的 i 已经是1了,但是哪个值赋给 i 呢?是副本还是原始数据?是副本,所以i = 0 。最终结果 i 是0而非1。

我们现在明白了这个后置递增运算符的执行步骤了,那我们来算一个复杂一点的后置递增运算语句:

let i = 10;
i = i++ + i++;
console.log(i);

我们直接解读这一部分(i = i++ + i++)的执行步骤:
首先我们拆分大体的执行步骤:

  1. i++
  2. +
  3. i++
  4. i = ?

  1. 这个后置递增运算符执行完,就会另外增加一块内存(副本),那么就有两块内存,一块是副本10,一块是原数据11。从上面的讲解得出,被当做操作数的是副本而不是原始数据,所以10被当做操作数。

  2. 10 + 多少呢?我们接下来看下一步。

  3. 此时的 i 是多少了,从第一步可以得出,i 已经是11了,然后老规矩,复制–>递增之后副本是11,原始数据是12,副本被当做操作数,那么就是 10 + 11 = 21

  4. i = ? ,又到赋值部分了,21赋值给 i ,i 的最终结果是21

最后我们再来看一段代码:

let i = 10;
console.log(i++);

当第二行码执行完,i 已经是11,但是被当做操作数输出的不是原始数据而是副本,所以输出10。

注意点

i++后置递增运算符是一个整体,自然它的执行步骤也不能被拆开(复制–>递增),这个两个步骤是紧紧连在一起的。

我们来看一个将后置递增运算符的执行步骤拆开之后的运行结果:

// 还是老演员哈
let i = 10;
i = i++ + i++;
console.log(i);

i = i++ + i++;

  1. i++ :复制一块副本10,原始数据10

  2. +:10 + ?

  3. i++:先复制,原始数据是10,所以副本也是10,10 +10 = 20 ,再递增,那么按道理来说应该递增两次,第一步还没有递增呢,递增两次,那么 i 原始数据为12。

  4. i = ?:i = 20,最终结果是20 。这个结果对吗?不对。

我们再来复盘一下它的执行顺序,复制–>复制–>加法运算–>递增–>递增,两个后置递增运算符的执行步骤都被拆开了,导致得到错误的结果。正确的执行步骤应该是这样(复制–>递增)+ (复制–>递增),因为i++是一个整体,所以它的执行步骤用括号括起来便于理解。

总结

后置递增或者递减运算符,是先复制一块副本再递增或者递减原数据,副本被当做操作数而非原数据。

前置递增或者递减运算符,是先递增或者递减原数据再复制一块副本,副本被当做操作数而非原数据。它的副本和原数据的值都相同,所以前置这一块不会有什么疑惑的地方。

要把i++ ++i 或者i-- --i 看成一个整体,自然它们的执行步骤也不能被拆开。

ppt动画

如果你觉的看文字难以理解,我还做了一个ppt

测试代码

这个文件是一些更加复杂的前置后置递增递减运算符代码,感兴趣的话可以来测试一下,看一下你答对了吗?

测试代码

资料在百度网盘中,如果要提取码,那么就是:1111

参考资料

参考文章:1234

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值