今天在课上学了闭包,概念都很明白,但是在应用时候会有很大问题,跟大家分享一下.
- 首先什么是闭包呢?
引用大牛阮一峰老师的话来说就是“闭包就是能够读取其他函数内部变量的函数”.阮老师的原文网站说的很简单,但是他举了一个例子:
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
这就是一个闭包,函数f1内新建了一个函数f2并且f1内部声明了一个局部变量 n,
但是Javascript语言特有的”链式作用域”结构(chain scope)决定了子对象会一级一级地向上寻找所有父对象的变量,父对象的所有变量,对子对象都是可见的.但是父级对象对子级对象中的变量却不可见.所以通过 return f2;将f2作为返回值便可在外部调用f2中的函数,也就是alert(n);
f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
我想这可能是一个最简单的闭包了,当然学习闭包要对变量作用域有一个大概的了解.
在这篇文章中找到了一些更全面的回答 这位老师对于每个人对闭包不同的理解整理的很详细,让我觉得受益匪浅,在这里我也引用一下:
简单理解(基本)
闭包是一个函数。
细化(来自阮一峰博客)
闭包是定义在一个函数内部,并且能够读取其他函数内部变量的函数。
明确(来自《JavaScript高级程序设计》第三版)
闭包是定义在一个外部函数内部,并且能够访问(存取)外部函数中自由变量的函数。
广义抽象(来自Mozilla与维基百科)
闭包是一个抽象的环境记录,它包含狭义的闭包函数以及在创建该函数时,每个自由变量及其值或名称绑定存储区直接的一个映射。
当然,使用闭包也有注意的点:
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。上文中f1因为是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
作为一个初学者,我的理解都是来源于这些有经验的老师们,感谢他们的分享,待我以后有了自己深入的理解我再来将这篇博文补全,欢迎大家积极交流,我将受益匪浅..