功能
延长变量生存周期
一个经典的例子,这个时候我们就可以看到变量会随着函数的退出而随着作用域销毁。如果我们想要长久的保存这个变量怎么办,这个时候,我们就可以用到闭包了。
再举一个例子,我们都知道 Object.prototype.toString.call(this) === '[object XXXX]'
用来判断类型是一个非常好用的例子,如果我们需要判断多个类型的话。当然不会像这么来写:
因为这样的话有着太多的重复代码了,而且我们可以发现代码中有太多相同的内容,这个时候我们就可以使用闭包来进行处理了。
这样就可以快速的生成方法了,当然,如果我们不用闭包来生成方法又会如何呢?
可以看出,生成的方法并没起来类型判断的作用
用于封装变量
大家都知道, js 相对于其它语言,没有 private 私有这个概念。如果某些时候,我们希望使用私有变量的时候,这个我们可以使用闭包来封装变量,来实现私有变量这个方法。
我们也还可以用它来持久化储存静态变量
因为函数是高级公民,我们还可以用于保存函数。
概念
我们通过了几个简单的小例子来演示闭包了,通过例子可以很轻松的理解刚开始学习 js 时看到阮一峰老师的博客里关于闭包的概念闭包就是能够读取其他函数内部变量的函数。
再回想我们的例子,是不是每次都是返回新的函数,函数里运用了一些参数,但是这些参数并没有在函数中声明,而是在函数的上级作用域中声明了,因为这些参数一直处于被引用状态,所以垃圾回收机制并没有销毁它们,而是让其常驻在内存中,所以我们就可以在其它的地方调用返回的函数,并继续引用这些参数。
面向对象中的闭包
还可以这么写
在 ES6 中甚至是理所应当
闭包与内存
关于闭包对于内存的影响,阮一峰老师曾经在博客写写道 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
, 甚至还有一些耸人听闻的说法如 闭包会造成内存泄漏,所以要尽量减少闭包的使用
。之所以这么说的原因是,变量本应该随着函数的退出而解除引用。但是因为我们使用闭包,我们主动的把一些本应该销毁的变量常驻于内存中留待下次使用。如果仅仅是因为这个原因让我们放弃使用闭包,这无异于端起碗吃饭,放下碗骂娘
。我们把这些变量放在闭包的作用域与放在全局作用域上,对内存的影响是一致的,不过还因为使用闭包,避免了全局变量名污染。如果固执的以为这样对内存有不好的影响,那么可以手动的置为 null