JavaScript 闭包

日期: 2017-07-20         浏览量: 3175

今天来聊聊闭包,闭包对 JavaScript 程序员来说是一个难懂又必须征服的概念。闭包的形成与变量的作用域以及变量的生命周期密切相关。下面我们先了解这里个知识点。



变量的作用域:


变量的作用域,就是指变量的有效范围。

在声明一个变量时,如果改变量前面没有添加关键字 var ,那么这个变量就会成为一个全局变量。

如果在函数内部使用 var 关键字声明一个变量,那么这个变量就成为一个局部变量。只有在该函数内部才能访问这个变量。

var func = function(){

    var a= 1;

    console.log(a);    //输出1      

}

func();

console.log(a);       //输出 Uncaught ReferenceError: a is not defined


注:变量的搜索的从内到外,而非从外到内。



变量的生命周期


除了变量的作用域外,另一个和变量有关的概念就是变量的生命周期。

对于全局变量的生命周期是永久的,除非我们主动的去销毁这个全局变量。

而对于在函数内部使用 var 关键字声明的局部变量,在退出函数时,这些局部变量即失去了他们的价值,他们也会随着函数调用的结束而被销毁。


var func = function(){

    var a = 1;            //退出函数后局部变量a将被销毁

    console.log( a ); 

}

func();


来看下面的这段代码:


var func = function(){

    var a= 1;

    return function(){

        a++;

        alert(a);

    }

}

var f = func();

f();      //2

f();      //3

f();      //4

f();      //5


根我们之前的结论相反,当退出函数后,局部变量 a 并没有消失。而是似乎一直在某一个地方存活。这是因为当执行 var f =func(); 时,f 返回了一个匿名函数的引用,它可以访问到 func() 被调用时产生的环境,而 a 一直处于这个环境里。 既然局部变量所在的环境还能被外部访问,这个局部变量就有了不被销毁的理由。在这里有产生了一个闭包的结构。