0%

我对Javascript中的闭包Closure的理解

怎样理解 Javascript Closure 也就是闭包的概念,想必很多人在为此头疼。 笔者先后参考了下面这些资料

作者们都声称自己搞懂了闭包的概念,可自己还是看的云里雾里。 直到笔者看到下面这篇文章,才开始真正理解闭包的概念和应用场景。 Jonathan D. Johnson的博客 http://jondavidjohn.com/javascript-closure-explained-using-events/ 下面我试着把这篇文章边翻译边把自己的理解写出来。 先看一下下面这段程序, 效果:在第3次按下button的时候显示”Third time’s the charm”的消息框。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// declare counter outside event handler's scope
var counter = 0;
var element = document.getElementById("button");

element.onclick = function() {
// increment outside counter
counter++;

if (counter === 3) {
// do something every third time
alert("Third time's the charm!");
// reset counter
counter = 0;
}
};

程序中声明了一个全局变量counter,每次按下button都会唤起程序,从而让counter++ 如果你只在自己的网页中执行一次的话,这么写也无所谓,但是如果你想在其他地方复用的话, 最好还是把这段程序封装成单独的一个函数。 这时问题就来了,你要每次都声明一个外部的全局变量counter吗?很明显这种做法太笨拙。 于是closure的作用就发挥出来了。 如果你看过了MDN的解释,就会知道closure其实是这样一种机制,

函数可以访问它被创建时所处的作用域中的对象(Object)。

于是上面那段程序利用闭包可以优化成下面这种形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<input type="submit" id="button1" value="button1" class="button"/>
<input type="submit" id="button2" value="button2" class="button"/>

<script>
var myClosureFunc = function () {
// init the count to 0
var count = 0;
return function (e) {
//count
count++;

if (count === 3) {
// do something every third time
alert("Third time's the charm!");
//reset counter
count = 0;
}
};
}

var element1 = document.getElementById("button1");
element1.onclick = myClosureFunc();

var element2 = document.getElementById("button2");
element2.onclick = myClosureFunc();
</script>


</body>
</html>

  counter的位置移到了event handler函数的内部,而函数的返回值为一个闭包。 按照上面的概念,myClosureFunc中的闭包可以访问它创建时所处的作用域(scope), 于是它就可以访问自己的counter,而这个counter是相对全局的,也就是说,在element1被按下的过程中,这个counter是共有的。 而element1和element2中的counter又是相对独立的。 怎么样,有没有帮你理解closure在作用域这个概念里所起的作用?