选择页面

Javascript中的闭包是比较难的概念,本文截取部分自JavaScript面向对象编程指南的内容,对闭包的概念进行解释。

在了解闭包之前,首先要熟悉作用域链,因为闭包的出现是为了突破作用域链。

作用域链

如果我们在一个外部函数outer()中嵌套了一个内部函数inner(),那么在inner()中可以访问的变量既来自于它自身的作用域,也可以来自其父级的作用域,这样就形成了一个作用域链。

var global = 1;
function outer () {
    var outer_local = 2;
    function inner() {
        var inner_local = 3;
        ruturn inner_local + outer_local + global;
    }
return inner();
}

// 执行
> outer();
> 6

闭包

var a = "global variable";
var F = function(){
    var b = "local vaiable"
    var N = function() {
        var c = "inner local";
    };
};

首先a至于全局空间中,b位于F空间中,c位于N空间中,其中,a和b是不联通的,因为b在F之外是不可见的,但是如果我们讲c和b联通起来,把N空间扩展到F以外,我们就产生了一个有趣的东西,叫做闭包

这样以来,N和a就同处一全局空间,因为函数还记得被定义时的环境,所以N仍然可以反问F空间和b,但是a却不能访问F空间和b。这主要是通过将它们升级为全局变量/通过F传递给全局空间实现的。

例子

通过F传递的方法:

var a = "global variable";
var F = function(){
    var b = "local vaiable"
    var N = function() {
        var c = "inner local";
        return b; // b在全局空间中不可见
    };
    return N;
};
var inner = F();// b对N是可见的,因为F 是全局函数,所以将F的返回值赋值给另外一个全局变量,从而生成一个可以访问F()私有空间的新全局函数;
> inner();

通过升级为全局变量的方法:

var inner; //定义全局变量
var F = function(){
    var b = "local vaiable"
    var N = function() {
        var c = "inner local";
        return b; // b在全局空间中不可见
    };
    inner = N;
};
var inner = F();// b对N是可见的,因为F 是全局函数,所以将F的返回值赋值给另外一个全局变量,从而生成一个可以访问F()私有空间的新全局函数;
> inner();

简而言之,如果一个函数在其父函数返回之后,仍然可以留住对父级作用域的链接,相关的闭包就会创建起来