闭包(closure)是 Javascript 语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。小编之前一直糊里糊涂的,没有能够弄明白 JavaScript 的闭包到底是什么,有什么用,本文把自己的理解些出来分享一下,希望不理解 JavaScript 闭包的朋友们看了之后能够理解闭包!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
在 javascript 中,函数可看作是一种数据,可以赋值给变量,可以嵌套在另一个函数中。
- var fun = function(){
- console.log("平底斜");
- }
- function fun(){
- var n=10;
- function son(){
- n++;
- }
- son();
- console.log(n);
- }
- fun(); //11
- fun(); //11
我们把上面第二段代码稍微修改下:
- var n=10;
- function fun(){
- function son(){
- n++;
- }
- son();
- console.log(n);
- }
- fun(); //11
- fun(); //12
看出差别了吗,如果理解不了代码执行结果,请看上一篇博文,关于 javascript 作用域和作用域链的讲解。
上面这段代码中变量 n 是全局变量,随时可能被重新赋值,而无需通过 fun 函数的调用。为了让变量 n 不受污染,或者说是减少全局变量的污染,我们需要把 n 放到函数中作为局部变量。
- function fun(){
- var n=10;
- function son(){
- n++;
- console.log(n);
- }
- son();
- }
- fun(); //11
- fun(); //11
如果我们可以在全局中直接调用 son 函数,那么便可以达成想要的效果。son 函数现在是作为局部变量存在,要想在全局中访问,一般有两种方法:
一种是赋值给全局变量
- var a;
- function fun(){
- var n=10;
- a = function son(){
- n++;
- console.log(n);
- }
- }
- fun(); //son()
- a(); //11
- a(); //12
另一种是使用 return 返回值
- function fun(){
- var n=10;
- return function son(){
- n++;
- console.log(n);
- }
- }
- var a=fun();
- a(); //11
- a(); //12
上面的 son() 函数就是闭包,某种意义上所有函数都可以看作闭包。闭包就是可以访问外层函数作用域的变量的函数。
- var a;
- function fun(){
- var n=10;
- a = function son(){
- n++;
- console.log(n);
- }
- return a();
- }
- fun(); //11
- a(); //12
- a(); //13
- fun(); //11
- a(); //12
- a(); //13
还是上面那段代码,我们稍微修改下,再看看执行结果,这是因为每次执行 fun() 函数时都会初始化变量 n。
闭包的好处是减少全局变量,避免全局污染,可以将局部变量保存在内存中。但这既是优点又是缺点,一段代码中如果闭包过多,有可能造成内存泄露。由于闭包中局部变量不会被垃圾回收机制回收,所以需要手动赋值为 null(关于内存泄露,后期单独开专题)
来源: http://www.phperz.com/article/17/0219/267723.html