闭包两个实例的自我理解

闭包与变量的经典实例

一、闭包导致变量泄露为全局变量

function CreatFunction(){
	var result=[];
	// var j=5;
	for (var i =0; i <10; i++) {
	result[i]=function() {
            return i;
        };
	   }
    
return result;

}
CreatFunction()

也就是高程书上说的:闭包只能取得包含函数中任何变量的最后一个值。
原因:
下图是该函数的运行结果,result=包含了10个函数的数组
在这里插入图片描述
而这个数组的每一个f()={return i;}
在这里插入图片描述
也就是说,内部仅仅声明某一个函数,引擎并不会对函数内部的任何变量进行查找或赋值操作。只会对函数内部的语法错误进行检查,也就是说,这个f()并没有执行,结果只是把函数返回了,此时如果进一步让函数去执行,那么根据闭包的原理,一:因为是闭包,内部函数调用了createfunction作用域里面的i,所以i不会消失;二:根据作用域链,内部函数会去外部作用域也就是CReatfunction()作用域里面寻找i,并赋值给内部函数,当然此时,定义的函数已经运行完毕了,也就是for循环已经运行完了,此时i=10,所以运行结果如下图:
在这里插入图片描述

二、该问题的修正

1、用立即执行函数进行修正
高程书上是这么修改的:创建另一个匿名函数强制让闭包的行为符合预期

function CreatFunction(){
	var result=[];
	// var j=5;
	for (var i =0; i <10; i++) {
	result[i] = (function (val) {
       return function () {
               return val;
   };
 })(i);
    }
return result;

}
CreatFunction();

为了保证返回值也是个函数,所以在第5行加了一个立即执行函数,这样得到的结果也是一个包含十个函数的数组
在这里插入图片描述
但与上一个不同的是,该函数没有把闭包直接赋给数组,而是用了一个匿名立即执行函数嵌套起来,相当于给内部函数function
function() {return val; }加了一个块级作用域,它仍然是闭包,但是因为函数function(val)是按值传递的,所以i会赋值给val这个形参,让函数function(val)把内部函数包起来,不让val泄露到全局中,也就可以保证,数组依次执行结果是0123456789
在这里插入图片描述
2、用let进行修正
let有块级作用域,因此就相当于4-8行被包含进了for的这个块级作用域中,从而把i锁定。

 function CreatFunction(){
    	var result=[];
    	// var j=5;
    	for (let i =0; i <10; i++) {
    	result[i]=function() {
                return i;
            };
    	   }
        
    return result;
    
    }
    CreatFunction()

运行结果如下:
在这里插入图片描述
简要图示:
在这里插入图片描述
我尽力了,再写下去就疯了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值