学习笔记——闭包

198 阅读3分钟

第一篇文章,想记录关于闭包的学习笔记,顺便整理一下自己的思路

什么是闭包?

只要有权访问另一个函数作用域变量的函数都是闭包,阮一峰说的闭包:“闭包就是能够读取其他函数内部作用域变量的函数”。事实上,每个函数都可以是一个闭包,因为每个函数都可以在其所在域中维护某种私有联系。
在讨论闭包之前,javascript的变量作用域了解一下。
变量作用域无非就两种:全局作用域、函数作用域。
函数作用域就是在某函数内定义的所有变量在该函数外是不可见的。但如果该变量是在代码块中被定义的(如在某if或者for语句中),那么它在代码块外是可见的。

有一个地方要注意的是在函数内部定义变量时需要使用var语句,如果没有的话则是声明了一个全局变量。
每个函数都有一块属于自己的私有空间,用来存储一些变量或者内部函数。
var a=1;
var F = function(){
    var b=2;
    var N = function(){
        var c=3;
    };
};
很明显,上面声明的a为全局变量,位于全局空间中,b则是位于函数F()的空间中,在这个空间里,我们可以访问全局空间,也可以访问F空间。c是位于函数N()的空间中,在这个空间里,我们可以访问全局变量、F空间和N空间。而b在F空间外是不可见的,ab是不连通的。
![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/3/18/162384b0807eb81f~tplv-t2oaga2asx-image.image)
当然,我们也可以将他们连通。当我们将N的空间扩张到F空间以外,并止步于全局空间的时候,闭包就产生了。此时,N与a一样都位于全局空间,而且由于函数会记得它被定义时的环境,因此N此时可以访问F空间并使用b,而a则不可以。
如何能实现这一操作?只需将N升级为全局变量(不使用var语句)或者通过F传递(或返回)给全局空间就可以了。
如下
var a=1;
var F = function(){
    var b=2;
    var N = function(){
        var c=3;
        return b;
    };
    return N;
};
>b
Uncaught ReferenceError: b is not defined
>var f=F();
>f();
2
或者
var f;
var F = function(){
    var b=2;
    var N = function(){
        var c=3;
        return b;
    };
    f=N;
};
>f();
2
我们在F空间内定义了函数N,并将它赋值给全局变量f,由于N()是在F()中定义的,所以它可以访问F空间,即使N升级为全局函数,但它仍然保留对F()作用域的访问权。
简单的来说,闭包就是可以访问另一个函数作用域变量的函数。

闭包有什么用呢?

闭包最大的用途:
1.读取函数内部的变量
2.让这些变量的值始终保持在内存中