关于闭包的面试题引发的思考

闭包

一直想写个闭包的总结,无奈自己理解的太渣,不敢乱写,最后还是想写一点东西。
关于闭包,在我目前学习的理解中,就是闭包它是会驻留在内存中,不会被js垃圾回收机制清除,因此它也是模拟的全局变量,也就是说它的this指向window。而目前我的知识范围的闭包就是函数内部又定义了一个函数,由于js的作用域链是由里向外,也就是只有内部的函数可以去找外部的变量。而你外部要想取到我内部的变量,那么闭包就派上用场。你可以通过return来获取到内部的变量。

示例1

 function box(){
  var arr=[];
  for(var i=0;i<5;i++){
   arr[i]=function(){
     return i;
   }
  }
  return arr;
}
var b=box();
for(var i=0;i<5;i++){
  alert(b[i]());
}
典型的闭包问题,alert全是5。为啥?仔细看,当你执行到alert这行时,arr是不是已经执行得到了?也就是说你是之后再进行box()()的调用,也就是函数内部的函数是b[i]()时执行。那么你第一个for循环是不是已经执行完毕得到i=4?由于循环执行完毕,又加了一次,也就是结果是5。没有问题,那么要怎么去解决它呢?首先你要想得到0,1,2,3,4那么就是把它们存在一个地方,也就自然的想到了闭包,因为闭包可以将变量存起来。那么改写如下:
function box(){
  var arr=[];
  for(var i=0;i<5;i++){
   arr[i]=(function(i){
     return function(){
         return i;
     }
   })(i)
  }
  return arr;
}
 匿名函数function(){return i}将变量i存储在内存中。利用了闭包的特性。还有一种方法,你直接让他立即执行,不是在调用的时候执行,不也是得到正确的结果么?
function box(){
  var arr=[];
  for(var i=0;i<5;i++){
   arr[i]= function (){
    return i ;
      }();
  }
  return arr;
}
var b=box();
for(var i=0;i<5;i++){
  alert(b[i]);
}
其实简单粗暴直接arr[i]=i;也能得到结果。

示例2

知乎上看到的题目:
  for(var i=0;i<5;i++){
      setTimeout(function(){
      console.log(i);
    },1000*i)
  }
  执行的结果是5,5,5,5,5隔一秒一个5。为啥?和上面的类似,你延时执行,哪怕是0秒他也不是立即执行,涉及到定时器函数队列的问题,还不是太明白。意思就是你设置了定时器,他会将函数放到类似的执行队列上,而没有设置定时器的函数依然在他前面执行。回到这题,你延时执行,for循环已经走完,i=5,结果就是一秒一个5。
  解决问题:
  1.想到闭包:
  现在想让i=0,1,2,3,4是吧,也就是说你内部将i存起来,不就解决了么。也就是:
  for(var i=0;i<5;i++){
    (function(t){
     setTimeout(function(){
      console.log(t);
    },1000*t) 
    })(i)
  }
  2.如果你立即执行,不也可以么?
   for(var i=0;i<5;i++){
     setTimeout((function(){
      console.log(i);
    })(),1000*i) 
  }
 不过这样写问题也在,你会立马输出0,1,2,3,4。

以上就是目前我对闭包的理解,其实感觉还是很模糊的概念。就是知道有那么个东西但是用不好,可能是我现阶段的知识层面还没有达到那个层次。最后,写的可能有不对的地方欢迎指正~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值