【Web前端问题】JS作用域和闭包

图片描述

这里的 i 是指向全局的 i 所有全部都是10,这个没问题

然后我把i写在函数里面,把他变成局部
图片描述

然后点击BUTTON 输出全部都是 4 也就是btn.length 这个好理解,绑定事件回调函数指向都是局部变量的i,问题来了,事件绑定是异步的,f1()调用完后,f1函数的局部作用域要释放。点击BUTTON为什么还是4,请问这里形成闭包了吗?有没有大神解释下

然后

图片描述

这里又是怎么理解?求大神分析

回答:

形成闭包了。

f1的局部作用域没有释放,因为在click的回调函数中保持了对i变量的引用,因此i不会被垃圾回收算法回收

==================

对于题主补充的图片:

这里是使用function创造了一个局部作用域,并把i的值传进去,对于每个click回调函数,他访问的i都来源于不同的IIFE,因此值是不同的。

回答:

第二段里面console.log(i)还在引用i,所以是不会释放i的。
第三段形成了闭包,闭包内部查询i的时候在参数中查找到i了,就不会再向外去查找了。

回答:

是的,形成闭包了。回调函数在执行完之后不会被回收,因为它将等待未来被调用。而此回调函数又引用了f1作用域里的变量,所以f1的整个作用域都未被回收,形成闭包。

回答:

第一段代码执行的结果是这样的:

a[0] = function(){console.log(i)};//这里函数体里的i还没有被执行 下同

a[1] = function(){console.log(i)};

a[2] = function(){console.log(i)};

a[3] = function(){console.log(i)};

a[4] = function(){console.log(i)};

a[5] = function(){console.log(i)};

a[6] = function(){console.log(i)};

a[7] = function(){console.log(i)};

a[8] = function(){console.log(i)};

a[9] = function(){console.log(i)};

当执行完for循环后 i的值就变成10了 这样再调用任意的a[i] 都是输出10

第二段和第一段没区别啊 就类似于把第一段写在一个函数内 那么函数一执行 不就和第一段一样了么?

btn[0] = function(){ alert(i) };

btn[1] = function(){ alert(i) };

btn[2] = function(){ alert(i) };

btn[3] = function(){ alert(i) };

for循环结束后i的值变为4,任意点击按钮,都是输出4。

第三段的话是典型的闭包 引用上面"dablwow80"的话 function创造了一个局部作用域,每个i都是独立的~

回答:

第一段,作用域,全局/局部/块级
第二段,i作为局部变量,并不会被GC,for循环仍在引用
第三段,函数作为参数传递,闭包

回答:

你4个button的那个js,你没有把for循环中的i当作参数传入进事件中,你调用了最外面的f1(),也只是执行这个函数里面可执行的程序段,也就是说你for循环确实在执行了,但是循环里面的监听事件你不会去触发,那么无论你怎么监听,你的i最后输出只会是4。给你看一个log大法你应该就能明白了图片描述

而你最后一个程序那是把i当参数传进去了,所以你会输出每个i值,其实现在你完全可以用es6的语法直接一键搞定这个问题,把var改成let就行
图片描述

以上是 【Web前端问题】JS作用域和闭包 的全部内容, 来源链接: utcz.com/a/138081.html

回到顶部