JavaScript闭包初探

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript闭包初探相关的知识,希望对你有一定的参考价值。

闭包使用的代码部分参考了W3C和饥人谷公开课,谢谢。

1.什么是闭包?

W3C:闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量

要较好理解闭包,除了形式本身,还应先理解:JS没有块级作用域;JS的内存回收机制(可见JavaScript作用域)。

 

2.闭包的例

闭包是一种结构,getName引用了外部变量name,形成闭包。第9行把name赋给变量whoname,使name在内存中保持。如果没有getName形成闭包,People函数执行完,其name变量就被释放。

1 function People(){
2      var name = ‘xiaohua‘;
3      function getName(){
4           return name;
5      }
6      return getName;
7 }
8 
9 var whoName = new People();

 

3.闭包容易引起的bug

 

var result = [];
function foo(){
    var i = 0;
    for(;i<3;i++){
         result[i] = function(){
              alert(i);
         }
    }   
}

foo();

result[0](); //3 
result[1](); //3 
result[2](); //3 

 这是因为i始终存在,没有块级作用域,i最后等于3,result数组中的所有函数里的i都指向那个等于3的i。解决办法是给函数传参数。

 

4.闭包的几个用途

  • 隔离作用域

JS虽然没有块级作用域,但是有函数作用域。为了使变量之间不会有命名冲突,使用立即执行函数把作用域隔离。下面的两个作用域内的name互不影响,无意间形成了闭包的结构。如果没有隔离作用域

 1             (function(){
 2                 var name = ‘aa‘;
 3                 
 4                 function a(){
 5                     return name;
 6                 }
 7             })();
 8             
 9             (function(){
10                 var name = ‘bb‘;
11                 
12                 function a(){
13                     return name;
14                 }
15             })();

 

  • 作计数器

 

 1             var counter = function(){
 2                 var count = 0;
 3                 return function(){
 4                     return ++count;
 5                 };
 6             };
 7              
 8             var countAdd = counter(); // function(){ return ++count; };
 9             countAdd();           //1
10             countAdd();           //2
11             alert(countAdd());    //3

 

  • 声明私有变量

JS本身没有私有变量、公共变量,静态变量的,都是模拟实现。下面如果把name作为People的属性,就无法实现私有。

 1 var People = (function(){
 2      var name = "xiaohua";
 3      function People(){};
 4      People.prototype = {
 5            getName:function(){
 6                  return name;
 7            },
 8             setName:function(newName){
 9                  name=newName;
10            }
11      };
12      return People;
13 })();
14 
15 var p = new People();

 

以上是关于JavaScript闭包初探的主要内容,如果未能解决你的问题,请参考以下文章

javascript闭包的理解

JS---闭包

javascript 匿名函数及闭包----转载

JS闭包以及作用域初探

Groovy 本质初探及闭包特性原理总结

PHP闭包(Closure)初探(转载 http://my.oschina.net/melonol/blog/126694?p=2#comments)