简要描述对闭包的理解

函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性称为闭包。这意味着函数变量可以隐藏于作用域链之内,看起来好像是函数将变量包裹了起来。这种方式常用于共享函数内的私有变量。
闭包有如下应用特征:

1、局部变量:在函数中定义有共享意义(如:缓存、计数器等)的局部变量(注:定义成全局变量会对外造成污染);

2、内嵌函数:在函数中声明有内嵌函数,内嵌函数对函数中的局部变量进行访问;

3、外部使用:函数向外返回此内嵌函数,外部可以通过此内嵌函数持有并访问声明在函数中的局部变量,而此变量在外部是通过其他途径无法访问的。

     var n = 10;
    function counter() {
        var n = 0;
        var g = function () {
             return ++n;
            };
        return g;
    }
    var c1 = counter();
    console.log(c1());
    console.log(c1());
    console.log(c1());

上述代码运行后,分别输出数字 1、2、3。
首先从应用上分析,这是一个闭包的典型应用:模拟计数器。调用一次函数counter,则得到一个计数器,即代码中的变量 c1,用于统计被调用的次数;每运行一次计数器c1,则访问次数加1。因此分别输出数字1、2、3。
其次从代码原理来分析:函数 counter 返回其内嵌函数g,该函数中包裹了函数 counter 的局部变量 n,其初始值为 0;每次运行函数g,均访问相应的局部变量 n,从而实现累加计数的效果。


 for (var i = 0; i < 3; i++) {
     setTimeout(function () { alert(i); }, 3000);
    }

上述代码希望实现:3s后弹出三次警告对话框,对话框中显示的数字分别为0、1、2。问,上述代码能否实现所需要的效果?如果不能,应该如何实现?

上述代码不能实现所需要的效果。会在 3s 后弹出三次警告对话框,对话框中的数字均为 3。
这是因为,循环结束后,变量i的值为3;当 3s 后运行循环中内嵌的函数,执行语句 alert(i) 时,访问的是循环中的变量 i。因此,三次弹出均为数值3。
如果希望实现分别弹出数字 0、1、2,需要将代码修改如下:

 for (var i = 0; i < 3; i++) {
        (function (n) {
            setTimeout(function () { alert(n); }, 3000);
        })(i);
    }

修改后的代码中,使用匿名函数封装一次性定时器的代码,并在调用匿名函数时,将变量 i 的值作为参数传入。每次循环中,调用一次匿名函数,则启动一个定时器对象,将相应的数字传入。3s后执行函数时,不再访问循环中的局部变量i,则会依次弹出0、1、2。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泠泠在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值