摘要:在中,闭包其实随处可见。但真要说起什么是闭包的话,很多人可能一时半会不知道怎么解释。这篇博文主要写一些闭包的特性已经相关的应用。
在JavaScript中,闭包其实随处可见。但真要说起什么是闭包的话,很多人可能一时半会不知道怎么解释。这篇博文主要写一些闭包的特性已经相关的应用。定义
参考资料:阮一峰——JavaScript运行机制详解
闭包是指在函数声明时的作用域以外的地方被调用的函数,在函数声明时的作用域以外的地方调用函数,需要通过将该函数作为返回值或者作为参数被传递
特性光看定义的话可能会比较懵逼(╯‵□′)╯︵┻━┻ 下面来看一下闭包到底都有哪些特性:
函数在自己定义的词法作用域以外的地方执行
函数嵌套
访问所在的词法作用域
循环闭包 定义在循环中包含了函数定义则称为循环闭包
实例1讲了这么多,下面来看一段例子:
for(var i = 1; i < 6; i++){ setTimeout(function(){ console.log(i); },50); } //输出结果为: 6 6 6 6 6
好吧,如果你是新手的话,看到这里你是震惊的,因为作为一个萌新,当初我对这串代码的想法是这样的:
setTimeout函数在for循环中执行六次,每隔50ms输出一个数字,则会分别输出1、2、3、4、5
后来我发现,用关键字var声明的变量会存在变量提升的情况,循环结束以后,变量i不会被JavaScript引擎的垃圾回收机制回收,而是成为全局变量。
所以我的的初步解释为:
由关键字var声明的变量存在变量提升的情况,循环结束以后变量i变为全局变量
for循环结束的比50ms要早,所以setTimeout函数读取不到迭代的变量i,而是循环结束后的变量i
实例2然而上面只是我一开始错误的认识,直到我看到下面的代码:
for(var i=1;i<6;i++){ setTimeout(function(){ console.log(i); },0); } //输出结果为: 6 6 6 6 6
因为这里setTimeout的时间参数是0,如果照着上面的思路来的话,这里的输出应该是 1 2 3 4 5
JavaScript调用机制在讲述解决方法之前我们先来了解一下JavaScript的调用机制
对JavaScript比较熟悉的人应该了解,JavaScript是一种单线程的语言。而我们在编写代码的时候,往往不止同步的代码,还有异步执行的代码,JavaScript这里把它分成两种模式,一种叫做同步任务,另一种则叫做异步任务。在执行代码的时候,同步任务被分配在主线程中执行,形成一个调用栈;而异步任务则交给浏览器的其他线程去执行。当异步任务执行完毕以后,则将对应的异步任务放入任务队列中。当调用栈中的任务都执行完毕以后,再读取任务队列,取消对应任务的等待状态,然后进入调用栈,开始执行。解决方法
方法1:绑定作用域,将关键字var改为let,具体代码为:
for(let i=1;i<6;i++){ setTimeout(function(){ console.log(i) },50) }
方法2:运用IIFE(立即执行函数),具体代码为:
for(var i=1;i<6;i++){ (function(j){ setTimeout(function(){ console.log(j) },50) })(i); }
在迭代内部使用IIFE会为每个迭代生成一个新的作用域,使得延迟函数的回调可以将新的作用域封闭在每个迭代内部,每个迭代都含有一个具有正确值的变量供我们访问
总结闭包在JavaScript里随处可见,我们在使用闭包的时候,需要谨慎的在循环内部添加闭包。个人觉得最好的解决方案就是使用关键字let,可读性强而且另代码整洁,希望ES6能够全面普及。
扫描下方的二维码或搜索「tony老师的前端补习班」关注我的微信公众号,那么就可以第一时间收到我的最新文章。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/85016.html
摘要:大名鼎鼎的闭包面试必问。闭包的作用是什么。看到闭包在哪了吗闭包到底是什么五年前,我也被这个问题困扰,于是去搜了并总结下来。关于闭包的谣言闭包会造成内存泄露错。闭包里面的变量明明就是我们需要的变量,凭什么说是内存泄露这个谣言是如何来的因为。 本文为饥人谷讲师方方原创文章,首发于 前端学习指南。 大名鼎鼎的闭包!面试必问。请用自己的话简述 什么是「闭包」。 「闭包」的作用是什么。 首先...
摘要:完美的闭包,对,闭包就这么简单。这仅仅是闭包的一部分,闭包利用函数作用域达到了访问外层变量的目的。此时一个完整的闭包实现了,的垃圾回收机制由于闭包的存在无法销毁变量。 1.闭包是指有权访问另一个函数作用域中的变量的函数。 上面这段话来自 javascript 高级程序设计 第三版 P178 。作者说闭包是一个函数,它有访问另一个函数作用域中的变量的能力。 2.函数访问它被创建时所处的...
摘要:到底什么是闭包这个问题在面试是时候经常都会被问,很多小白一听就懵逼了,不知道如何回答好。上面这么说闭包是一种特殊的对象。闭包的注意事项通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。从而使用闭包模块化代码,减少全局变量的污染。 闭包,有人说它是一种设计理念,有人说所有的函数都是闭包。到底什么是闭包?这个问题在面试是时候经常都会被问,很多小白一听就懵逼了,不知道如何回答好。这个...
阅读 1910·2021-11-15 17:58
阅读 2115·2021-10-19 11:45
阅读 3440·2021-09-02 15:40
阅读 2574·2021-07-25 10:50
阅读 3727·2019-08-30 15:56
阅读 3129·2019-08-30 12:44
阅读 1013·2019-08-26 13:38
阅读 1854·2019-08-23 18:29