Javascript里的闭包

在Javascript里,函数可以访问自己的上层作用域,即使上层已经关闭

今天去网上学习的时候,才发现 Javascript 里的 闭包 跟我最近发现的一个编程方式是一样的……所谓 思而不学则殆 吗(笑)

比如,我要自增一个数字,可以这样

1
2
3
4
5
6
7
8
9
10
11
var num = 0;
function addNum(){
++num;
}
addNum();
hCon.log( num );
addNum();
hCon.log( num );

这样确实可以达到要求,可问题是,num可以被外部修改,如此,我们应该将num放在addNum里。

1
2
3
4
5
6
7
8
function addNum(){
var num = 0;
return ++num;
}
hCon.log( addNum() );
hCon.log( addNum() );

然而,问题来了,结果始终都是 1,因为每次函数执行的时候,作用域都不是一样的

所以,改怎么办呢?之前我想过用构造函数的方式来做

1
2
3
4
5
6
7
8
9
10
11
12
13
function addNumConstructor(){
var num = 0;
this.addNum = function (){
return ++num
};
}
var addNum = new addNumConstructor;
hCon.log( addNum.addNum() );
hCon.log( addNum.addNum() );

然而这样并不是闭包,只是一种面向对象[1],如何不用面向对象实现呢?

这就是闭包

1
2
3
4
5
6
7
8
9
10
11
var addNum = (function (){
var num = 0;
return function (){
return ++num;
}
})();
hCon.log( addNum() );
hCon.log( addNum() );

由此想到的一个计时器:

1
2
3
4
5
6
7
8
9
10
var myTimer = (function ( ele ){
var num = 0;
return function (){
$(ele).text( num++ );
}
})( hCon.log('这是个计时器') );
setInterval(myTimer, 1000);

当然,由此也延伸出一个新的概念——高阶函数[2],我将在以后的时间里再开一篇介绍它


  1. 所谓的然并卵 ↩︎

  2. 返回值是函数的函数 ↩︎