JavaScript闭包是一个比较难理解的概念。官方英文的定义是:Closure (also lexical closure or function closure) is a function together with a referencing environment for the non-local variables of that function。那种感觉又来了:每个单词都懂,但是连起来瞬间就懵了- -#。
今天查阅了不少资料,打算好好理解一下。
根据英文解释可以大概知道,闭包其实就是一个函数和它对非本地变量的引用的统称。从定义上来说,在Javascript中,每个function都是闭包,因为它总是能访问在它外部定义的变量。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
首先来看一个典型的面试题:
<script src="jquery-1.4.4.js"></script>
<script>
$(function(){
var num = 1;
$("p").each(function(){
$(this).click(function(){
alert(num);
});
num++;
});
});
</script>
1
2
3
4
5
问题:点击五个P标签各输出什么?
<script src="jquery-1.4.4.js"></script>
<script>
$(function(){
var num = 1;
$("p").each(function(){
$(this).click(function(){
alert(num);
});
num++;
});
});
</script>
1
2
3
4
5
理解问题的关键在于理解Javascript的机制,Javascript是解释型的语言,一个函数在被调用的时候才会解释执行。例子中的click事件绑定的函数构成闭包,它引用了外部的"num"变量,注意是引用,而不是复制。在我们点击时函数才会执行。正是由于对变量有了引用,javascript垃圾回收机制不会回收它,此时的变量“num"驻留内存中,所以它的值是最终的”6"。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
再来看另一个例子:
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------闭包的应用
function Counter(start){
var count = start;
return{
increment:function(){
count++;
},
get:function(){
return count;
}
}
}
var foo = new Counter(4);
alert(foo.get());// 4
foo.increment();
alert(foo.get());// 5