闭包与变量

JS高程中关于闭包与变量这一节,讲到一个案例,我当时看的一脸懵逼,然后就自习的研究了一下,先上代码:

	function createFunctions(){ 
	 	var result = new Array(); 
 		for (var i=0; i < 10; i++){ 
 			result[i] = function(){ 
	 			return i; 
			 }; 
	 	} 
 		return result; 
	}

	//调用最外层函数,接收返回的数组
	var arr = createFunctions();
	// 循环遍历数组,调用每个元素并打印
	for (var i = 0; i < arr.length; i++ ) {
		console.log(arr[i]()); //10
	}

为啥是10个10呢,乍一看,循环的时候,返回的i应该是对应的索引啊,那么打印出来的应该是0-9才对,也就是这样:

	result[0] = function() { return 0; };
	result[1] = function() { return 1; };
	result[2] = function() { return 2; };

其实这个问题的关键在于,函数是啥时候被调用的
在调用createFunctions这个函数之后,返回的result数组实际上是这样的:

	result[0] = function() { return i; };
	result[1] = function() { return i; };
	result[2] = function() { return i; };

而当我们去调用数组中的元素时,数组元素对应的匿名函数才会被调用,此时返回i,很显然,当前作用域中并没有i,那么就需要到他的上一层作用域去找,而这个时候,循环结束, i已经是10了,所以我们无论调用数组中的哪个元素,返回的都是10;

问题的关键就在于,我们没有立即使用i这个变量,而是把它保存在起来,需要的时候再调用,而i这个变量一直在变化,所以我们需要在循环的每一步中,实时地获取i的值,解决方案如下:

	function createFunctions(){ 
	
 		var result = new Array(); 
 		
 		for (var i=0; i < 10; i++){ 
 		// 给result[i]一个自调用函数,并实时地将i作为参数传递给变量num
 			result[i] = function(num){ 
		 		return function(){ 
	 				return num; 
	 			}; 
			}(i);
	 	} 
		 return result; 
	}

函数createFunctions被调用之后,在for循环中,自调用函数立即执行,获取实时地i赋值给num. 循环结束之后,返回result:

	result[0] = function() { return num;};
	result[1] = function() { return num;};
	result[2] = function() { return num;};

此时我们再调用数组元素时,闭包函数会去他的上层作用域中寻找num的值,(虽然用i给num赋值的自调用函数在被调用之后,它的执行环境的作用域链就被销毁了,但是它的活动对象还在闭包函数的作用域链中,)所以会返回对应的元素下标.

也是参考一些大佬的经验才稍微理解了一些,不足的地方欢迎指正,此贴主要是用来记录总结学习过程中的问题.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值