1.闭包可以简单理解为一个匿名内部类
2.理解闭包必须先理解作用域链
举例:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style type="text/css">
</style>
</head>
<body>
<input type="button" name="button" value="button" οnclick="mclick()">
<script type="text/javascript" src='js/jquery-1.11.1.min.js'></script>
<script type="text/javascript">
var data=[];
for (var i = 0; i < 3; i++) {
data[i]=function () {
console.log(i)
}
}
data[0]();
data[1]();
data[2]();
</script>
</body>
</html>
在这个列子中的作用域链:
最外层window对象(包含属性data,i),二级链:3个函数对象(data,i)
注:下级链中会共享上级(祖先)链中的所有属性
案例1:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style type="text/css">
</style>
</head>
<body>
<input type="button" name="button" value="button" οnclick="mclick()">
<script type="text/javascript" src='js/jquery-1.11.1.min.js'></script>
<script type="text/javascript">
var data=[];
for (var i = 0; i < 3; i++) {
data[i]=function () {
console.log(i)
}
}
data[0]();
data[1]();
data[2]();
</script>
</body>
</html>
结果:3 3 3
我的分析理解:data数组有三个元素,每个元素都是一个函数,即函数对象,每个函数对象中都有一个属性i,从上面的作用域链中可以知道3个函数对象中使用的i是共享至外层全局变量i,可以这样理解有4个i 这个是个i分别所属于不同的对象,外层i所属于window对象,其他3个i所属于3个函数对象,但他们指同一块内存区域,当循环结束后外层对象中的i变成了3,因为引用同一块内存区域所以3个函数对象中的i也变成了3,所以在只需3个函数时结果未 3 3 3
案例2:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style type="text/css">
</style>
</head>
<body>
<input type="button" name="button" value="button" οnclick="mclick()">
<script type="text/javascript" src='js/jquery-1.11.1.min.js'></script>
<script type="text/javascript">
var data=[];
for (var i = 0; i < 3; i++) {
data[i]=(function (k) {
return function () {
console.log(k);
}
})(i);
}
data[0]();
data[1]();
data[2]();
</script>
</body>
</html>
结果:1 2 3
分析:在for循环中给数组定义三个函数,函数的产生是通过执行3个匿名函数返回的。在执行匿名函数时,将返回3个函数对象,即这个程序中总共有7个对象,window对象,3个里面函数对象(在执行后就变成了垃圾等待系统进行销毁),3个返回的函数对象,在这里作用域链是这样的,最外层是window对象包含属性i,data,二级链上对象是3个平行的匿名函数对象包含属性k,i,data 三级链上对象是3个返回的函数对象包含属性k,i,data。在循环中执行3个匿名函数传递参数的方式将外层的i属性的3个值传递进3个匿名函数中的k,而返回的3个函数中的k是共享至二级链中的匿名函数对象,所以结果是 1 2 3