Discuss / JavaScript / 详解

详解

Topic source

来自某博文。很感谢

首先我们弄懂上面代码的运行流程:首先var results = count();之后,函数count已经被调用了,所以一次执行函数内的各段代码:var arr = [];for (var i=1; i<=3; i++),这个for循环尤其值得注意。因为此时循环体执行了push方法,将一个个函数function () { return i * i;}添加到数组内,但是这个函数并没有被调用,还只是一个变量,所以for循环依次执行,直到i = 4。因为闭包,内部函数function () { return i * i;}引用的i就是外部变量,for循环中的i = 4。所以,之后数组arr内的函数的i都是4。

​ 调用函数count后,变量results已经是数组arr了。数组里面元素依次是function f1() { return i * i;} function f2() { return i * i;} function f3() { return i * i;}。但是三个函数都没有被调用,直到var f1 = results[0];,此时function f1() { return i * i;}开始执行,如上段所写,此时的i = 4,所以,返回值就是16了。后面两个调用也是类似情况

感谢!按这个思路来看完全明白了!奥利给!

老哥,result[0]怎么来理解

result 本质就是这个有三个元素的数组,不过这三个元素都是同一个函数:function() { return i * i;},且只与i 有关,这时i=4。

所以result[0]=result[1]=result[2]=function() { return 4 * 4;}=16

伦敦阴雨

#5 Created at ... [Delete] [Delete and Lock User]

感谢,理解到了关键;arr【】数组内存放的是一个个函数。再由于闭包的原因,函数并不是立即执行,在arr[]内部以(i*i)等待执行,而是在之后调用时,i为4。才会出现都等于16的情况

玩转ACE

#6 Created at ... [Delete] [Delete and Lock User]

感谢感谢,1楼的大神是不是打快了,有个点理解不一样:

 直到var f1 = results[0];,此时function f1() { return i * i;}开始执行

应该是在var f1 = results[0];,此时还没有开始执行函数,而是等到调用`f1()`时,function f1() { return i * i;}才开始执行吧?不知道理解是不是正确;

紫陌ol

#7 Created at ... [Delete] [Delete and Lock User]

把for 循环的var i 换成 let i 就没问题了. 他这个例子用的不好, 造成这个原因并不是因为闭包, 而是因为var 的自动提升问题.

紫陌ol

#8 Created at ... [Delete] [Delete and Lock User]

我纠正一下我的说法, 我的说法是错误的. 关于var 和 let导致for循环闭包的区别 请看这篇文章 

https://zhuanlan.zhihu.com/p/28140450


  • 1

Reply