在最近在js的学习中,我接触到了js之中一个比较难的模块:闭包。但是这个模块却可以在js程序中发挥巨大的作用,本文以学习过程中的一个经典实例作为例子讲述对闭包作用的收获。
实例代码1
在下列的代码里,我想实现的是,当点击 <ol>
中各个<li>
时,页面会弹窗显示四个不同的数字
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<ol>
<li>第一项</li>
<li>第二项</li>
<li>第三项</li>
<li>第四项</li>
</ol>
<script type="text/javascript">window.onload=function () {var lis =document.getElementsByTagName('li');for (var i =0; i <lis.length; i++) {
lis[i].onclick=function () {alert(i);};}}</script>
</body>
</html>
但是实际的结果是,在不同的<li>
上点击时,弹出的窗口显示的数字都是4(黑人问号??)
经过查阅资料以及课程老师的讲解,我明白了这个问题出现的原因:在这个例子里面,alert(i)
的this
是window
,(原因是,alert对应的的作用域是对应的<li>
,而它的方法里面alert的作用域是window
) 所以在鼠标点击这个事件调用函数之前,早在页面加载的过程中,for循环已经完成,得到的i都是值为4
所以为了使得原来的需求能够实现,我们可以使用函数闭包,将变量i加入到事件处理器onclick
的函数闭包之中,实现如下:
实例代码2
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<ol>
<li>第一项</li>
<li>第二项</li>
<li>第三项</li>
<li>第四项</li>
</ol>
<script type="text/javascript">window.onload=function () {var lis =document.getElementsByTagName('li');for (var i =0; i <lis.length; i++) {
lis[i].onclick=function (i) {returnfunction () {alert(i);}} (i);//利用IIFE实现函数闭包,将i作为参数传入即可}}</script>
</body>
</html>
有什么不严谨的地方还望各位看官指出!