JS原型和闭包

来源:互联网 发布:node.js 开发web的优势 编辑:程序博客网 时间:2024/06/01 08:21

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里更是如此了,<?phpfunction parent(){  global $m;//全局 ,定义与赋值要分开  $m=50;}parent();echo $m;//50?>//没global的话,一样会报没定义的错误

有时,需要得到函数内部的的局部变量,就需要变通的方法实现

利用js变量作用域的特点,如在函数内部定义子函数,对于子函数来说,父函数就是它的全局,子函数可以访问父函数里的变量(对于整个js代码来说又是局部变量)

 

<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未定义

注意 在javascript里,在函数里声明的函数都是局部的,函数运行完后就释放了

注意这点与php的区别

 

<?phpfunction parent(){  function son(){      $m=50;      echo $m;  }}parent();son();//输出50 不会报错?>

 

闭包

函数内部定义函数,连接函数内部和外部的桥梁

闭包的作用有2:

一是前面提到的读取函数内部的变量,

二是让这些变量的值保存在内存中,实现数据共享

下面是几个闭包的例子

<script type="text/javascript">var cnt=(function(){    var i=0;    return function(){        alert(i);        i++;    }})();cnt();//0cnt();//1cnt();//2cnt();//3</script>

把匿名函数的执行结果(即对里面子函数的声明赋给全局变量cut),i就保存在内存里了

执行cut()时就直接从内存取值了,i只有cnt()函数才能调用,直接alert(i)是不行的

还可以向闭包内传参

var cnt=(function(num){return function(){    alert(num);    num++;  }})(5);cnt();//5cnt();//6cnt();//7//当然还可以调用时传参var cnt=(function(){    var i=0;return function(num){    num+=i;    alert(num);    i++;  }})();cnt(1);//1cnt(2);//3cnt(3);//5

为了对闭包有更好的理解,我们看以下代码

比如我想返回一个数组,数组里面有5个函数,第一个函数弹出0,第二个弹出1...

  代码如果这样写

function box(){  var arr=[];  for(i=0;i<5;i++){      arr[i]=function(){return i;}    } return arr;   }var a=box();alert(a);//包含五个函数体的数组alert(a[0]());alert(a[1]());

弹出的函数体

function(){return i;}

    

}

最后这个i4,之后++成为5

For循环停止

发现均弹出5,明显不符合我们的要求

解决方案1

自我即时执行里面的函数

function box(){  var arr=[];  for(i=0;i<5;i++){      arr[i]=(function(num){return i;})(i);    } return arr;   }var a=box();for(var i=0;i<a.length;i++){  alert(a[i]);}

但是我们发现 返回的数组里的元素是函数执行的结果,但我们想要的是函数

有得升级我们的代码

解决方案闭包实现

 

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);

 

 

 

 这就是闭包的好处!
0 0
原创粉丝点击