js 闭包

为啥需要闭包,闭包要解决什么问题?

<!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 

来自:https://www.cnblogs.com/junjingyi/p/9191792.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值