资讯专栏INFORMATION COLUMN

假如技术HR问您JavaScript的“闭包”,嘿嘿嘿,举这个例子就够了

fjcgreat / 1389人阅读

摘要:概念当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

概念

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

例子 问题

下面的代码的运行结果和代码语意上表达的不相符,我们希望它能够每隔一秒输出一次,每次输出对应的数字,即第一秒后输出1,第二秒后输出2......
而这段代码的运行结果是,第一秒后输出6,第二秒后输出6......
请解释原因并且提出修改方案。(包含要点,函数作用域,块作用域,闭包,let)

for (var i = 1; i <= 5; i++) {
    setTimeout(function timer() {
        console.log(i);
    }, i*1000);
}
答案 解释原因

var i,实际上声明了一个全局变量

延迟函数timer必然是在循环结束后才开始执行,循环结束后,i=6

循环中确实定义了多个延迟函数timer,延迟函数在setTimeout的内部被回调,根据闭包概念,timer在其声明之外的地方被调用,timer能够记住并访问其声明位置的词法作用域,存在闭包

实际上timer所记住的词法作用域就是全局作用域,所以引用输出的i都是6

修改方案

只要能保证每次循环都能够创建新的作用域,在新作用域中保存当前i的值即可

所以任何可以创建新作用域的方法都可以达到效果,具体可参考这里,通过分析这段代码的进化历程,或许能够加深您对JavaScript的作用域的理解

常见的做法有

利用具名立即执行函数,每次循环都创建新作用域

for (var i = 1; i <= 5; i++) {
    (function scope(j) {
        setTimeout(function timer() {
            console.log(j);
        }, i * 1000);
    })(i);
}

利用es6 let创建块作用域

for (var i = 1; i <= 5; i++) {
    {
      let j = i;
      setTimeout(function timer() {
            console.log(j);
        }, i * 1000);
    }
}
总结

根据闭包的概念,只要有回调就会有闭包......
记住这个例子,还怕被问闭包?

后记

最近写了三篇,参考书籍主要是《你不知道的JavaScript(上卷)》,看完这三篇可以说就相当于看了半本书了,^_^
前端框架层出不穷,不反对使用框架,但一定要有头头能驾驭的了它。试想,做前端的人那么多,如果冰河世纪来临,存活下来的还是那些会写框架的人,那些只懂框架使用的人就危险了
我快毕业了,但心里慌慌的,所以如果您刚入门,建议还是扎扎实实地学基础,其实JS基础远比您想象的要复杂,千万别以为自己看了W3C School就觉得自己Ok了,反正我是要再努力下,争取看得懂牛人的代码哈
下篇见......

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79370.html

相关文章

  • 来!我们一起来从头开始构建自己JavaScript模块化工具

    摘要:能达到一个积木块模块的要求。接下来我们将改进它。结尾到此,我们自己构建了一个很实用的模块化工具,项目的源码在这里,喜欢的话,给个。 前言 希望编写程序能像玩积木一样,首先规划要产出怎样的作品,然后在积木堆中挑选合适的积木块,最后一组合就完工了。 于是JavaScript需要类似这样模块化,每个模块都隐藏内部细节并且对外暴露接口,再处理好模块之间的依赖关系,就可以达到玩积木的效果了。 虽...

    AaronYuan 评论0 收藏0
  • JavaScript闭包,只学这篇够了

    摘要:当在中调用匿名函数时,它们用的都是同一个闭包,而且在这个闭包中使用了和的当前值的值为因为循环已经结束,的值为。最好将闭包当作是一个函数的入口创建的,而局部变量是被添加进这个闭包的。 闭包不是魔法 这篇文章使用一些简单的代码例子来解释JavaScript闭包的概念,即使新手也可以轻松参透闭包的含义。 其实只要理解了核心概念,闭包并不是那么的难于理解。但是,网上充斥了太多学术性的文章,对于...

    CoderBear 评论0 收藏0
  • 深入理解JavaScript,这一篇够了

    摘要:也就是说,所有的函数和构造函数都是由生成,包括本身。如果只考虑构造函数和及其关联的原型对象,在不解决悬念的情况下,图形是这样的可以看到,每一个构造函数和它关联的原型对象构成一个环,而且每一个构造函数的属性无所指。 前言  JavaScript 是我接触到的第二门编程语言,第一门是 C 语言。然后才是 C++、Java 还有其它一些什么。所以我对 JavaScript 是非常有感情的,毕...

    villainhr 评论0 收藏0
  • Kafka参数调优实战,看这篇文章够了!【石杉架构笔记】

    摘要:那这条消息的延迟就是秒钟。避免一个迟迟凑不满,导致消息一直积压在内存里发送不出去的情况。个人公众号:石杉的架构笔记(ID:shishan100)目录1、背景引入:很多同学看不懂Kafka参数2、一段Kafka生产端的示例代码3、内存缓冲的大小4、多少数据打包为一个Batch合适?5、要是一个Batch迟迟无法凑满咋办?6、最大请求大小7、重试机制8、持久化机制 1、背景引入:很多同学看不懂k...

    cloud 评论0 收藏0
  • postman工具入门使用,有她够了

    摘要:安装此处先省略算了我还是分享一下吧嘿嘿链接提取码至于安装步骤选择好安装路径直接就可以了了解功能模块能点进这篇文章的人就不用介绍是用来干什么的了帮助我们本地测试方式本地测试方式本地测试方式测试文件的上传功能我以文件为例方 ...

    freecode 评论0 收藏0

发表评论

0条评论

fjcgreat

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<