Js闭包
闭包前要了解的知识
1. 函数作用域
(1).Js语言特殊之处在于函数内部可以直接读取全局变量
<script type="text/javascript"> var n=100; function parent(){ alert(n); } parent();//100 </script>
如果在php里
<?php $n=100; function parent(){ echo $n; } parent();//会报错 n未定义 ?>
(2).在函数外部无法读取函数内的局部变量
<script type="text/javascript"> function parent(){ var m=50; } parent(); alert(m);//报错 m未定义 </script>
注意函数内部声明变量时一定要加var,否则就声明了一个全局变量
function parent(){ m=50; } parent(); alert(m);//50
//当然在php里更是如此了, <?php function parent(){ global $m;//全局 ,定义与赋值要分开 $m=50; } parent(); echo $m;//50 ?> //没global的话,一样会报没定义的错误
有时,需要得到函数内部的的局部变量,就需要变通的方法实现
利用(对于整个)
<script type="text/javascript"> function parent(){ var m=50; function son(){ alert(m); } return son; } var s=parent();//将结果保存在全局里 s();//50 </script>
Parent内部所有局部变量对其子函数来说都是可见的js特有的链式作用域结构,父对象的所有变量对子对象都是可见的,反之不成立!
上面的son函数就是闭包
有些同学可能这样
function parent(){ var m=50; function son(){ alert(m); } } parent(); son()//会报 函数son未定义
注意 在php的区别
<?php function parent(){ function son(){ $m=50; echo $m; } } parent(); son();//输出50 不会报错 ?>
闭包
函数内部定义函数,连接函数内部和外部的桥梁
闭包的作用有2个cut),i就保存在内存里了
执行,i只有alert(i)是不行的
还可以向闭包内传参
var cnt=(function(num){ return function(){ alert(num); num++; } })(5); cnt();//5 cnt();//6 cnt();//7 //当然还可以调用时传参 var cnt=(function(){ var i=0; return function(num){ num+=i; alert(num); i++; } })(); cnt(1);//1 cnt(2);//3 cnt(3);//5
为了对闭包有更好的理解,我们看以下代码
比如我想返回一个数组,数组里面有0,第二个弹出4,之后5
For循环停止
发现均弹出5,明显不符合我们的要求
解决方案2 闭包实现
function box(){ var arr=[]; for(var i=0;i<5;i++){ arr[i]=(function(num){ return function(){return num;} })(i); } return arr; } var arr=box(); for(var i=0;i<5;i++){ alert(arr[i]());//0,1,2,3,4 }
关键代码
arr[i]=(function(num){
return function(){return num;}
})(i);
i=0 时
arr[0]=(function(num){return function(){return num;}})(0);
1时
arr[1]=(function(num){return function(){return num;}})(1);
这就是闭包的好处!