Loading

谈谈我对JavaScript中闭包的理解

**

个人博客开通啦!功能正在逐步完善中,大家可以访问http://www.codeliu.com

**

闭包是JavaScript中比较重要的一部分,也是比较难的一个知识点。在看了阮一峰老师的关于闭包的博客后,感觉对闭包的理解更清晰了,有需要的同学不妨一看。
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html#comment-text 这是阮一峰老师文章的博客地址,下面我也做一个小小的总结,有兴趣的可以看看。

1.变量的作用域

要理解闭包,首先我们要理解一下变量的作用域,分为全局变量和局部变量。全局变量,就是在任何一个地方都可以被访问到,局部变量,就是只能在一定范围内被访问。

var n=1225;
function f1(){
    console.log(n);
}
f1();  //1225

上面定义的n就是全局变量,在函数内部也可以访问到。

function f1(){
    var n=1225;
    console.log(n);
}
f1(); //1225
console.log(n);  //undefined

上面定义的n就是局部变量,函数调用后会立即销毁,所有再访问n就无法取得它的值了。
但注意在函数里的定义的变量前面一定要加var,否则就变成全局变量了。看下面的代码

function f1(){
    n=1225;
}
f1();
n;  //1225

上面的代码中定义n时没有加var,这样n就是全局变量,在外面依然可以访问n。

2. 如何在外部访问函数内部的变量?

在正常情况下,因为在函数内部定义的变量都是局部变量,所以要在外部访问内部的变量,似乎是行不通的。

function f1(){
    var n=1225;
    function f2(){
        console.log(n);
    }
    return f2;
}
var result=f1();
result();  //1225

在上面的代码中,通过在函数内部定义另一个函数来获取n的值,这就是闭包。

3.什么是闭包?

在上面的例子中,f2就是闭包。闭包是什么?我认为闭包就是能够读取其他函数内部变量的函数,是连接外部和内部的桥梁。

在JavaScript语言中,只有在函数内部的子函数才能读取局部变量,因此可以把闭包理解为“定义在函数内部的函数”。

4.闭包的作用

1.能够读取函数内部的值
前面的代码已经展示了。

2.能让变量的值始终保存在内存中,不会被立即销毁。
前面我们说过,在函数内部定义的局部变量,在函数执行后,会被立即销毁,那闭包怎么让变量的值不被销毁呢?

function f1(){
    var n=1225;
    add=function(){
        n++;
    }
    function f2(){
        console.log(n);
    }
    return f2;
}
var result=f1();
result();   //1225
add();
result();   //1226

在上面的代码中,第一个result()执行后,打印出1225,执行add()后,再执行result()后,打印出1226,说明n没有被立即销毁。

result被定义为全局变量,f1是f2的父函数,而f2赋值给result,成为全局变量,f2的存在又依赖于f1,所以f1也始终存在于内存中,不会再调用结束后,被垃圾回收机制(garbage collection)回收。

这段代码中另一个值得注意的地方,就是”nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

5.使用的闭包的注意事项

使用闭包虽然有好处,但也有不足。

1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

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

posted @ 2017-09-23 10:27  CodeTiger  阅读(25)  评论(0编辑  收藏  举报