本文已参与「新人创作礼」活动,一起开启掘金创作之路。
js闭包是最重要的知识点之一,了解闭包对理解代码的作用很大,也是面试的重点知识,今天学习总结一下闭包相关的知识点。
什么是闭包?
闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数。有个关键词,另一个函数作用域中变量。我们知道,JS有全局作用域和函数作用域,全局作用域是都能访问,而函数作用域是只能在函数内部访问,那么闭包却可以实现一个函数访问另一个函数作用域中的变量。
闭包的用途(意义)?
- 我们在函数外部能够访问到函数内部的变量。通过使用闭包,我们可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量。
- 另一个用途是使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收。
闭包产生的原因?
当访问一个变量时,解释器会首先在当前作用域查找,如果没有找到,就去父作用域找,直到找到该变量或者不在父作用域中,这就是作用域链。
每一个子函数都会拷贝上级的作用域,形成一个作用域的链条。
闭包产生的本质就是,当前环境中存在指向父级作用域的引用。
闭包有哪些表现形式?
- 返回一个函数。
- 作为函数参数传递
- 在定时器、事件监听、Ajax请求、跨窗口通信、Web Workers或者任何异步中,只要使用了回调函数,实际上就是在使用闭包。
- IIFE(立即执行函数表达式)创建闭包, 保存了全局作用域window和当前函数的作用域,因此可以使用全局的变量。
var a = 2; (function IIFE(){ console.log(a); })();
为什么要用闭包
所有的变量,如果不加上var关键字,则默认的会添加到全局对象的属性上去,这样的临时变量加入全局对象有很多坏处,比如:别的函数可能误用这些变量;造成全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的)。除了每次使用变量都是用var关键字外,我们在实际情况下经常遇到这样一种情况,即有的函数只需要执行一次,其内部变量无需维护,可以用闭包
。
结果缓存:我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
总结:一、在全局作用域中读取内部函数的的变量,二、可以让闭包中引用的变量始终保存在内存中。