闭包练习题

var data = [];
for(var i = 0; i < 3; i ++) {
	data[i] = (function(i) {
		return function() {
			console.log(i);
		}
	}(i))
}
data[0]();
data[1]();
data[2]();
答案:0 1 2
 function fun(n, o) {
    	console.log(o);
    	return {
    		fun : function(m) {
    			return fun(m, n);
    		}
    	};
    }
    var a = fun(0);//这里第一次调用fun时输出undefined,返回了一个对象给a, n=0
   	a.fun(1);//这里首先调用了a对象的属相fun,属性fun,又调用了一个闭包函数,m = 1,返回一个fun(1,0)
             //执行fun(1,0),输出0,且又返回了一个对象 
	//console.log(typeof(a.fun(1)));//object
	a.fun(2);//返回的就是fun(2,0) //0
	a.fun(3);//返回的就是fun(3,0) //0

	var b = fun(0).fun(1).fun(2).fun(3)//fun(0)返回的是fun(0,0),fun(1)返回的是fun(1 , 0),输出0,这时n=1,fun(2)返回的是fun(2,1),输出1,这时n=2,fun(3)返回的是fun(3,2),输出2,这是n=3;
	var c = fun(0).fun(1); //undefined 0 
	c.fun(2); //1
	c.fun(3);//1
 function fn1() {
	   		for(var i = 0; i < 4; i ++) {
	   			var tc=setTimeout(
	   					function(i){
	   						console.log(i);
	   						console.log(tc);
	   						clearTimeout(tc)
	   					}, 10 ,i);

	   		}
	   }
	   fn1();
延迟10ms后执行的function(i),i的值是保存在第一个计时器执行的值。
而tc得值早就更新为创建第4个计时器返回得值。
第一次执行function(i)得时候,就清除了最后一个计时器,最后一个计时器根本没有执行

这道题主要考察了异步和闭包的问题
异步:js是单线程的,一次只能执行一个命令。js在执行时会生成一个主任务队列(先进先出),队列里按照顺序执行,当执行到setTimeout时,setTimeout会将里面的函数放到异步队列中,当 setTimeout执行完以后,js通过eventloop事件循环,发现异步队列中有任务等待,于是将其添加到队i列中开始执行.
所以tc最后保留的是创建最后一个计时器返回的值(tc = 4)之后才开始执行setTimeout里面的函数function(i)
闭包:即使setTimeout执行结束,但已经对内产生了闭包,当再执行function时使用的值的环境,仍然对应当时创建计时器执行时的作用域链,而tc没有被保留在闭包中,所以第一次cleartimeout(tc)时,就把最后一个计时器清除了,导致根本没有执行最后一setTimeout,所以输出得结果为 0 1 2

   function fn2() {
	   	for(var i = 0; i < 4 ;i ++){
	   		var tc=setInterval(function(i, tc){
	   			console.log(i);
	   			clearInterval(tc)
	   		},10,i,tc);
	   	}
	   }
每间隔10Ms,执行一次function(i,tc),tc得值也被保留在闭包中(创建一个计时器得环境中)
清除计时器在这里第一个值为undefined,i为1时才清除第一个计时器
使得保留最后一个计时器,每隔10ms就输出3。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值