js-闭包

178 阅读2分钟

注:整理阮一峰博客,关于闭包的知识点,感谢大佬

1.js语言特点

要理解闭包,首先要理解js的变量作用域。

变量的作用域:全部变量和局部变量

js的特殊之处在于:函数内部可以直接读取全局变量
如:
var a = 1;
function geta() {
    console.log(a) 
}
geta()//1

函数外部无法读取函数内部的局部变量

function geta() {
    var a = 'hello';
}
console.log(a) //Uncaught ReferenceError: a is not defined

2. 如何从外部读取局部变量?

由于种种原因,我们有时候需要得到函数内部的局部变量,正常情况下是无法读取的,只有通过一些变通的方法:

那就是在函数内部再定义一个函数。
function geta() {
    var a = 0;
    function getb() {
        alert(a)
    }
}
在以上代码中,getb被包括在了geta中,这个时候,geta中的所有变量对getb都可见,
getb可以读取geta中的所有变量,但是反过来是不行的,这是javascript语言特有的“链式作用域”结构,
子对象会一级一级地向上寻找所有父对象的变量,所以父对象的所有变量对子对象都是可见的,反之则不成立。

既然,getb可以读取geta中的所有变量,那么我们只需要把getb作为返回值,
就可以在geta的外部读取geta内部的变量了!
可以看下如下代码:
function f1(){
    var n=999;
    function f2(){
        alert(n); 
    }
    return f2;
}
var result=f1();
    result(); // 999

3.闭包的概念

2中的f2函数就是闭包。 闭包其实就是可以读取其他函数内部变量的函数,由于只有函数内部的子函数才能读取该函数的内部变量,因此可以把闭包理解为定义在一个函数内部的函数。

所以在本质上,闭包就是将函数内部与函数外部连接起来的一座桥梁。

4.闭包的作用

闭包有两个作用:
第一个就是像上面这样的,可以读取函数内部的变量。
第二个就让这些变量的值始终保存在内存中。

具体可阅读阮一峰博客---闭包

5.注意点

1.由于闭包会使得函数中的变量一直保存在于内存中,内存的消耗就很大,所以不能滥用闭包。否则就会造成网页的性能问题了,在IE中可能导致内存泄漏。

解决办法是:在退出函数之前,将不使用的变量全部删除

2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。