之前看到一个观点是 闭包是走向高级Javascript的必经之路,之前看过很多关于闭包的讲解帖子,一直没有理解透彻,模棱两可。
现在终于可以讲出来了。
检验自己有没有掌握一个知识,最好的方式是讲给一个不懂的人 ,给Ta讲懂了。我做到了。
请有心读者检阅我的知识点有么有错误。
一:什么闭包
首先要理解 js特殊的作用域机制:只能按照作用域链向上访问,而不能访问Ta下级域中的变量。
闭包:就是能够读取其他函数内部变量的函数。 (*^__^*)
一切函数某种环境下都可以当做闭包。
手写一个demo:
function a(){
var s = 1;
function b(){
s++;
}
}
上述中 b函数就是一个闭包。
二:闭包的用途:
1.可以读取函数内部的变量 2 使这些变量保存在内存中
举栗子:
var li = document.getElementsByTagName("li");
for(var i=0;i<5;i++){
li[i].onclick = function(){
alert(i);
}
}
这样运行结果是:每次弹出5; 原因是:当点击alert i的值为最后运算完的值。
修改方法一:
匿名函数自调用;
var li = document.getElementsByTagName("li");
for(var i=0;i<5;i++){
(function(arg){
li[i].onclick = function(){
alert(arg);
}
})(i);
}
-----------------分割线 -------------------
将变量 i 保存给在每个段落对象(p)上
1
2
3
4
5
6
7
8
9
|
function init() { var pAry = document.getElementsByTagName( "p" ); for ( var i=0; i<pAry.length; i++ ) { pAry[i].i = i; pAry[i].onclick = function () { alert( this .i); } } } |
2、将变量 i 保存在匿名函数自身
1
2
3
4
5
6
7
8
|
function init2() { var pAry = document.getElementsByTagName( "p" ); for ( var i=0; i<pAry.length; i++ ) { (pAry[i].onclick = function () { alert(arguments.callee.i); }).i = i; } } |
3、加一层闭包,i以函数参数形式传递给内层函数
1
2
3
4
5
6
7
8
9
10
|
function init3() { var pAry = document.getElementsByTagName( "p" ); for ( var i=0; i<pAry.length; i++ ) { ( function (arg){ pAry[i].onclick = function () { alert(arg); }; })(i); //调用时参数 } } |
4、加一层闭包,i以局部变量形式传递给内存函数
1
2
3
4
5
6
7
8
9
10
11
|
function init4() { var pAry = document.getElementsByTagName( "p" ); for ( var i=0; i<pAry.length; i++ ) { ( function () { var temp = i; //调用时局部变量 pAry[i].onclick = function () { alert(temp); } })(); } } |
5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)
1
2
3
4
5
6
7
8
9
10
|
function init5() { var pAry = document.getElementsByTagName( "p" ); for ( var i=0; i<pAry.length; i++ ) { pAry[i].onclick = function (arg) { return function () { //返回一个函数 alert(arg); } }(i); } } |
6、用Function实现,实际上每产生一个函数实例就会产生一个闭包
1
2
3
4
5
6
|
function init6() { var pAry = document.getElementsByTagName( "p" ); for ( var i=0; i<pAry.length; i++ ) { pAry[i].onclick = new Function( "alert(" + i + ");" ); //new一次就产生一个函数实例 } } |
7、用Function实现,注意与6的区别
1
2
3
4
5
6
|
function init7() { var pAry = document.getElementsByTagName( "p" ); for ( var i=0; i<pAry.length; i++ ) { pAry[i].onclick = Function( 'alert(' +i+ ')' ) } } |