闭包的含义: 闭包就是一个函数,两个函数彼此嵌套,形成闭包条件是内部函数需要通过return给返回出来
function f1(){ var age =20; var height =170; function f2(){ console.log("年龄"+age +"身高"+height) } return f2; } var ff = f1(); //ff就是一个闭包,其和f2共同指引同一个function ff(); //年龄20身高170
以上代码ff处于外部的全局环境,并且其调用的时候可以看到具体age和height内部输出
闭包的特殊之处在于,age和height是f1的内部环境变量,其在外部环境被访问出来
f1函数在执行完毕后,内部的信息要被销毁,age,height,f2均被销毁,f2被销毁后,垃圾回收机制要收走function,但是ff又去指引fai该函数,这样function内部的age和height也就依然存在,并且他们和外部的变量没有关系,因为他们已经固化为本身AO的成员信息,这样就会导致ff()执行的时候会有age和height信息输出
闭包的特点:闭包有权利调用其上级环境的变量信息
闭包使用规则:
同一个闭包机制可以创建多个闭包函数出来,他们彼此没有联系,都是独立的,并且每个闭包都可以保存自己个性化信息。
function f1(n){ function f2(){ console.log(n) } return f2; } var fa =f1(100); var fb =f1(120); var fc =f1(150); fa(); //100 fb(); //120 fc(); //150
闭包的应用场景:
1,实现数组的循环输出
var arr = new Array(); for(var i =0;i<4;i++){ arr[i] =function(){ console.log(i) } } arr[2]();//4 arr[0]();//4 arr[1]();//4 arr[3]();//4
循环以后生成的结果都是4,因为i是全局变量,所以都是在循环结束以后执行的函数,返回的结果都是4。要实现数组的循环输出,可以使用闭包实现
var arr = new Array(); for(var i=0;i<4;i++){ arr[i] = f1(i); } function f1(n){ function f2(){ console.log(n) } return f2 } arr[2]();//2 arr[0]();//0 arr[1]();//1 arr[3]();//3
引用2 : 设置事件
<script> window.onload = function(){ var cars = document.getElementsByTagName('li'); for(var i=0;i<3;i++){ cars[i].onmouseover = function(){ cars[i].style.backgroundColor = "grey" } } } </script> <h2></h2> <ul> <li>奔驰</li> <li>宝马</li> <li>奥迪</li> </ul>
上面代码会报错,使用闭包
<script> window.onload = function(){ var cars = document.getElementsByTagName('li'); //可以利用闭包给每个元素设置独立的函数处理 //并且函数内部也有独特的下标信息供访问 for(var i=0;i<3;i++){ //over和out分别是闭包机制,for循环会使得他们被分别执行3次 //这样会在内存中生成3个函数,每个函数内部有自己可以访问的独特信息 cars[i].onmouseover = over(i); cars[i].onmouseout = out(i); } //闭包 function over(n){ function f2(){ cars[n].style.backgroundColor ="pink" } return f2; } function out(n){ function f2(){ cars[n].style.backgroundColor ="" } return f2 } } </script> <h2></h2> <ul> <li>奔驰</li> <li>宝马</li> <li>奥迪</li> </ul>