为啥需要闭包,闭包要解决什么问题?
<!DOCTYPE html>
<html>
<head>
<meta charset="{CHARSET}">
<title></title>
<script type="text/javascript">
window.onload=function(){
var divs=document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
divs[i].onclick=function(){
alert(i)
// 执行完for循环之后,i的值已经变成了5,无论点击那个,弹出的都是5
}
}
}
</script>
</head>
<body>
<div>111</div>
<div>222</div>
<div>333</div>
<div>444</div>
<div>555</div>
</body>
</html>
解决
var divs=document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
//闭包的解决方案
divs[i].onclick=(function(j){
return function(){
//i是来自于全局作用域
alert(j)
}
})(i);
}
例子1
function fn(){
var a=5;
return function(){
a++;
console.log(a); //a变量肯定是可以访问的
}
}
var f1=fn(); //f1指向匿名函数
f1(); //6
f1(); //7
f1(); //8
//代码执行到8行fn函数执行完毕,返回匿名函数
// -->一般认为函数执行完毕,变量就会释放,但是此时由于js引擎发现匿名函数要使用a变量,所以a变量并不能得到释放,而是把a变量放在匿名函数可以访问到的地方去了
// -->a变量存在于f1函数可以访问到的地方,当然此时a变量只能被f1函数访问
例子2
function fn(){
var a=5;
return function(){
a++;
console.log(a); //a变量肯定是可以访问的
}
}
var f1=fn(); //f1指向匿名函数
f1(); //6
f1(); //7
f1(); //8
//把a变量的值放在f1函数可以访问到的地方
var f2=fn();
f2(); //6
f2(); //7
f2(); //8
//又一次执行了fn,又初始化了一个新的a变量,值为5;返回匿名函数f2,并且把新的a变量放在了f2可以访问到的地方
var f3=fn();
f3(); //6
//又一次执行了fn,又初始化了一个新的a变量,值为5;返回匿名函数f2,并且把新的a变量放在了f2可以访问到的地方
例子3
function q1(){
var a={};
return a;
}
var r1=q1();
var r2=q1();
console.log(r1==r2); //fasle
function q2(){
var a={}
return function(){
return a;
}
}
var t3=q2();//创建一个新的a对象,把a对象放在t3可以访问到的位置
var o5=t3(); //返回值a就是那个a
var w3=q2();//创建了一个新的a对象,把新的a对象放在w3可以访问到的位置
var o8=w3();//此时获取到的是一个新的a对象
console.log(o5==o8); //false
闭包的应用场景
模块化
防止变量被破坏
//模块化思想:也是一种设计模式
var ktv=(function KTV(){
//为了保护leastPrice变量,将它放在函数内部
var leastPrice=1000;
var total=0;
return {
//购物
buy:function(price){
total+=price;
},
//结账
pay:function(){
if(total<leastPrice){
console.log('请继续购物');
}else{
console.log('欢迎下次光临');
}
},
editLeast:function(id,price){
if(id===888){
leastPrice=price;
console.log("现在最低消费金额为:",leastPrice);
}else{
console.log('权限不足');
}
}
}
})()
//假设:来了朋友要来唱K
//——>可能老板需要去修改最低消费的金额
//-->但是并不能让老板直接去修改leastPrice,或者说不能把leastPrice作为全局变量
闭包问题的产生原因
函数执行完毕后,作用域中保留了最新的a变量的值
function f1(){
var a=5;
return function(){
a++;
console.log(a);
}
}
var q1=f1();
//要想释放q1里面保存的a,只能通过释放q1
q1=null; //q1=undefined