1. 开门见山
let i = 1;
i = i++;
console.log(i); // 1
2. 正常思路
按照“正常思路”,虽然第一步i=i=1;
但是 后面还有i = i+1 啊,所以应该是2吧
3. 探索
表达式都是有返回值的(temp),不然就不能放在赋值操作符右边了
而且无论多么复杂的表达式都是在表达式计算完后才返回一个值(temp)(注意是计算完后)
表达式 ++i 的返回值就是 i 自增后的值,而 表达式 j++ 的返回值是 j 自增前的值。
3.1 先来看看 i1 = ++i; 和 i1 = i++; 这种对结果没有歧义的情况:
int i = 1;
int i1 = ++i;
/** * 这一步可以理解为3步: * ① i = i+1 = 2; * ② int temp = i; * * ③ i1 = temp; * */
System.out.println(i1); // 2
int i = 1;
int i1 = i++;
/** * 这一步可以理解为3步: * ① int temp = i = 1; * ② i = i+1 = 2; * * ③ i1 = temp; * */
System.out.println(i1); // 1
对比来看
3.2 再来看看i=i++;
int i = 1;
i = i++;
/** * 这一步可以理解为3步: * ① int temp = i = 1; * ② i = i + 1 = 2; // 这一步虽然i自增了,i=2 * * ③ i = temp; // 但是这一步又把i重新赋值了,相当于第二步没有意义 * */
System.out.println(i1); // 1
3.3 对比思考
无论多么复杂的表达式都是在表达式计算完后才返回一个值(注意是计算完后) ,这句话很好。大部分人说的i2= i++ 先赋值后++,其实是不太对的,而且非常容易引起歧义的。
人们常说的先赋值,赋给的临时变量temp,而不是最终变量 i2 。
而且人们说的先赋值的“赋值”说的是第一步,而不是第三步
4. 知错能改
回到之前的“正常思路”,以为最后一步是 i++ , 但是其实最后一步是 i = temp;
而temp是i++以前赋值的,所以temp=1;因此++不会影响temp的值
这种之前的“正常思路”,其实割裂了i++作为一个表达式整体的概念 ,认为是先“赋值”,然后回到表达式来 ++ 。但实际应该是
表达式实 计算完后 才 返回一个值
5. 触类旁通
js,中也是同理
let i = 1;
i = i++;
console.log(i); // 1
6. 巩固一下
int i = 1;
i = i++;
int j = i++;
int k = i + ++i * i++;
System.out.println("i="+i);
System.out.println("j="+j);
System.out.println("k="+k);
int x = 5;
int y = 5;
if(x++==6 && ++y==6) {
x=11;
}
System.out.println("x=" + x + ";y=" + y);
int x = 5;
int y = 5;
if(x++==5 | ++y==5) {
x=11;
}
System.out.println("x=" + x + ";y=" + y);
参考资料:Java 中的 i = i++ 问题
文章评论