为了账号安全,请及时绑定邮箱和手机立即绑定

如何理解闭包

如何理解闭包

动漫人物 2019-03-13 13:14:12
1.使用var:var a = [];for (var i = 0; i < 10; i++) {  a[i] = function () {    console.log(i);  };}a[6](); // 102.使用letvar a = [];for (let i = 0; i < 10; i++) {  a[i] = function () {    console.log(i);  };}a[6](); // 6问题:在1中,循环内被赋给数组a的函数内部的console.log(i),里面的i指向的是全局的i,那a[i]的i岂不是也指向全局的i,那岂不是只有a[10]有值?
查看完整描述

7 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

1、循环中的语句是立即执行

2、每进一次循环,都会给数组第i项赋值

3、这里赋值的是个函数,但函数并没有执行

所以循环完了是这样的:


[

function(){console.log(i)},

function(){console.log(i)},

function(){console.log(i)},

function(){console.log(i)},

function(){console.log(i)},

function(){console.log(i)},

function(){console.log(i)}

]

//由于全局的i是10

//所以每一项打印都是10


查看完整回答
反对 回复 2019-03-27
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

for (var i = 0; i < 10; i++) {

  a[i] = function () {

    console.log(i);

  };

}

这里的a[i] 的意思相当于循环给a数组添加十个匿名函数function () {console.log(i);}; 你可以打印一下a你就知道了 a[i]是已经确立的了 至于执行a[6]相当于执行数组中的第7个匿名函数 打印i 这时候因为使用的是var 并不会产生块作用域 所以i的取值等于最外层循环结束的i值就是10


查看完整回答
反对 回复 2019-03-27
?
长风秋雁

TA贡献1757条经验 获得超7个赞

不要为了学闭包而闭包, 考虑闭包能做什么... 我感觉

首先,不要相当然的认为 程序按你的想法运行, 我感觉 计算机 算是一门严谨的科学。

js 词法作用域...

var a = [];

for (var i = 0; i < 10; i++) {

a[i] = (function (i) {


       return function () {

            console.log(i);

          };

})(i)

}

a[6](); // 6


//


查看完整回答
反对 回复 2019-03-27
?
忽然笑

TA贡献1806条经验 获得超5个赞

我从《你不了解的JS》总结了关于如何理解闭包:

  1. 某个函数拥有上级(或上多级)作用域的引用, 就叫做闭包

  2. 当函数记住并访问其所在的词法作用域, 即便它是在当前词法作用域之外执行, 这就产生了闭包

  3. 闭包可以使得函数就访问定义时的词法作用域, 所以实际上,只要使用了回调函数就使用了闭包

配合一段经典的面试代码就很好理解其一:

function Timer () {
    let time = 1
    return function () {
        console.log(time ++)
    }
}

关于题主的问题,相关闭包,但主要不在“闭包”上,应该是“var与let的作用域的问题”,只有当你了解了闭包并且了解了var与let作用域的不同才能想通这两个循环。

总结下JS的块级作用域(伪块级作用域):

  1. let

  2. try catch

  3. IIFE

  4. with(不推荐使用)

  5. 还有不。。记不清了


查看完整回答
反对 回复 2019-03-27
  • 7 回答
  • 0 关注
  • 662 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号