下面这段代码,我以为会输出1-10,结果输出的是5,而且不停地输出5,是个死循环,想不明白,求大神赐教。谢谢!
function initloop() { function doLoop(x) { i = 3; console.log(x); } for (var i = 0; i < 10; i++) { doLoop(i + 1); } } initloop();
光阴似箭催人老,日月如移越少年。
那个 i 其实相当于是在 initloop 里声明的.
function initloop() { var i = 0; function doLoop(x) { i = 3; console.log(x); } for ( ; i < 10; i++) { doLoop(i + 1); } } initloop();
这样看, 你脑补一下函数执行过程, 应该就明白了.每次循环, i 都会在 doloop 里被修改成 3, doloop 执行结束后, 执行 i++, 这时传入 loop 的实参应该就是 4 + 1;所以 console 先是1, 然后一直死循环输出 5.想要按你的想法输出 1 - 10, doloop 里的 i 加上 var.让它成为局部变量.
第一次循环 i=0,doloop实参 i+1即为1,所以第一次输出是1。因为doloop函数内没有i变量,会向外部作用域查找i变量,所以i=3会将循环体中的i赋值为3。第一次循环结束后因为i<10,所以i++即为4。从第二次开始i为4,所以dooloop实参为5,因为每执行一次dloop函数都会把i赋值为3,所以i始终小于10。结果就是第一次为1,然后循环打印5。
首先试运行了你的代码, 浏览器两次被卡死... 我为我的浏览器默哀...为此, 我才发现, 你的代码有毒...
实际运行时, 输入如下:
for循环第一次时, i===0, 执行doLoop(1), 因此doLoop函数内部, 形参x===1, 接着又改变了外部i的值, 重置为3, 故此时i===3, 紧接着打印出了x的值, 即1.
i===0
doLoop(1)
doLoop
x===1
3
i===3
1
for循环第二次时, 由于第一次循环结束时i===3, 发生自增操作, 即i++. 故i最终等于4. 4+1=5, 故执行doLoop(5),本次打印出了5. 函数内部重复上一次的操作, 外部i变量再次被重置为3,本次循环结束后i===5.
i++
4
4+1=5
doLoop(5)
5
i===5
for循环第三次时, 重复上次操作, i再次被重置为3, 再次打印5, 以此类推, 最终外层的for循环失效, 每次i的值都被重置为3, 循环结束条件无法满足. 故循环无法退出. 因此浏览器卡死.
总结下, 这样的写法是有问题的, 尽量不要在函数内部改变函数外部的变量.
每一次循环都把i赋值为3,而且dloop函数中的i又不是私有变量,所以每一次都会把initloop中的i赋值为3,下一次循环i++,i就变为4,传入dloop内自然每一打印的都是5,解下来dloop又把i变为3,i永远都不会等于10,所以死循环
那个 i 其实相当于是在 initloop 里声明的.
这样看, 你脑补一下函数执行过程, 应该就明白了.
每次循环, i 都会在 doloop 里被修改成 3,
doloop 执行结束后, 执行 i++, 这时传入 loop 的实参应该就是 4 + 1;
所以 console 先是1, 然后一直死循环输出 5.
想要按你的想法输出 1 - 10, doloop 里的 i 加上 var.让它成为局部变量.
第一次循环 i=0,doloop实参 i+1即为1,所以第一次输出是1。因为doloop函数内没有i变量,会向外部作用域查找i变量,所以i=3会将循环体中的i赋值为3。第一次循环结束后因为i<10,所以i++即为4。从第二次开始i为4,所以dooloop实参为5,因为每执行一次dloop函数都会把i赋值为3,所以i始终小于10。结果就是第一次为1,然后循环打印5。
首先试运行了你的代码, 浏览器两次被卡死... 我为我的浏览器默哀...
为此, 我才发现, 你的代码有毒...
实际运行时, 输入如下:
for循环第一次时,
i===0
, 执行doLoop(1)
, 因此doLoop
函数内部, 形参x===1
, 接着又改变了外部i的值, 重置为3
, 故此时i===3
, 紧接着打印出了x的值, 即1
.for循环第二次时, 由于第一次循环结束时
i===3
, 发生自增操作, 即i++
. 故i最终等于4
.4+1=5
, 故执行doLoop(5)
,本次打印出了5
. 函数内部重复上一次的操作, 外部i变量再次被重置为3
,本次循环结束后i===5
.for循环第三次时, 重复上次操作, i再次被重置为
3
, 再次打印5
, 以此类推, 最终外层的for循环失效, 每次i的值都被重置为3
, 循环结束条件无法满足. 故循环无法退出. 因此浏览器卡死.总结下, 这样的写法是有问题的, 尽量不要在函数内部改变函数外部的变量.
每一次循环都把i赋值为3,而且dloop函数中的i又不是私有变量,所以每一次都会把initloop中的i赋值为3,下一次循环i++,i就变为4,传入dloop内自然每一打印的都是5,解下来dloop又把i变为3,i永远都不会等于10,所以死循环