虽说提倡“退吧保智商”,不过我时常还会去瞄两眼的,毕竟贴吧在去年我人生最低谷的时候帮助我走了上来。刚刚在贴吧里看到一个并不很起眼的帖子for循环求值

本来看到这种帖子根本都不会去点开的,天知道我今天下午是不是被热坏了脑子打开看了一下那张图片。大意就是说这样一个循环执行之后j 的值为什么等于4:

1
for(i = 0; i < 5; i ++) j = i ++;

下面回复的有说“for的写法没有括号默认执行第一句”,虽然没有听过这个说法,不过我表示赞同。平时谁会这样用for 循环啊,自增量放到循环体里面用的场景我还真没见过==|||。

解决这个问题很简单,F12 开发工具跑一下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
for(i = 0; i < 5; i ++){
  console.log("before: i="+i+"\n");
  j = i ++;
  console.log("after: j="+j+"\n");
  console.log("after: i="+i+"\n");
}
// 结果:
// before: i=0
// after: j=0
// after: i=1
// before: i=2
// after: j=2
// after: i=3
// before: i=4
// after: j=4
// after: i=5

这样看明白了没有?在作 a = b ++ 这种运算时,是这样的:a = b; b ++ 。在 for 循环里也是这样的,判断完 i < 5 之后,先执行循环体,然后 i 的值增加 1 ,再继续下一次循环。如果没有 j = i ++ 这一句,而是 j = i 的话,j 的值就是从 0 到 4 ;但是这里第一个循环,到 j = i ++ 这一句时, i 的值为 0 , j = i ++ 实际等价于 j = i; i = i + 1 ,这样 j 第一个值为 0 ,之后 i 的值增加 1 ,再之后循环体结束, i 的值加 1 (这是 for 那个小括号里的 i ++ 语句),此时 i 的值为 2 。

顺着这种逻辑推理下去,够明白了吧?

搞清楚之后,可以尝试一下下面这种变体。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
for(i = 0; i < 5; ++i){
  console.log("before: i="+i+"\n");
  j = i ++;
  console.log("after: j="+j+"\n");
  console.log("after: i="+i+"\n");
}
// 结果:
// before: i=0
// after: j=0
// after: i=1
// before: i=2
// after: j=2
// after: i=3
// before: i=4
// after: j=4
// after: i=5

做过这个就会知道 for 循环的用法。在 for 循环里,自增运算符的位置其实无关紧要,自增量总是在整个循环体结束之后加 1 。可以参照 C 语言相关的书,或是这里:for 循环中的i++ 和 ++i有什么区别?