再读闭包

143 阅读2分钟

前言

每次被问什么是闭包时,有以下答案:

1. 函数内返回一个函数。

2. 可以访问私有变量的函数。

。。。

但是,看着上面的答案,其实我还是一脸懵逼了,以至于再问到闭包在工作中的作用时,我是这么回答的:

其实也没啥吊用。。

其实如果你能真正描述出什么是闭包时,你也能够想到闭包的作用。那么什么是闭包:

闭包是由函数和创建该函数的词法环境组成的。这个词法环境包含了该函数被创建时可以访问的所有局部变量。

还是一脸懵逼?简洁一点就是:

闭包 = 函数 + 该函数可以访问的一个对象。

举个例子:

function parentScope() {
    var name = '父亲';
    return function() {
        console.log(name)
    }
}
var Closures = parentScope();

Closures变量是parentScope返回的匿名函数的引用,而这个匿名函数是在parentScope函数内部声明的,可以访问parentScope
下的局部变量(name)。所以Closures = 匿名函数 + 匿名函数可以访问的词法环境。所以Closures就是一个闭包。

知道了什么是闭包,那闭包到底有什么用呢?其实从上面认识闭包可以得出:

1. 通过闭包可以在函数外部访问函数作用域内的局部变量。

那除了这个作用,还有其他作用吗?

实现js的模块化(module pattern)。webpack实现的模块化就是利用了闭包:

// module1.js
function (module, module.exports) {
    var private = 'jack';
    module.exports = {
        getPrivate() {
            return private;
        }
    }
    return module.exports;
}

webpack通过将我们的业务代码用一个函数包裹,并且传入module.exports对象,使其他模块可以使用这个模块的方法,进而访问到这个模块的私有变量。想一想,我们平时怎么用模块的:

var m = require('module1.js'); // 此时m就是上面导出的module.exports对象
m.getPrivate() // 返回module1中的私有变量。

所以,通过闭包,即实现了私有变量,又可以通过闭包来实现模块化。