前端面试题中常见的会犯错的题目-作用域链剖析

        网上经常可以查到很多的前端面试题,很多都是很基础的东西,但是仍然不免有很多的童鞋会出错,不是因为他们技术不够啊什么的,很多时候就最基础的东西忘记了而已;

        我们来看这样的一段简单的前端面试题中的代码: 

var data = [];
for(var i=0;i<3;i++){
    data[i] = function(){
        console.log(i);
    };
}
data[0]();
data[1]();
data[2]();

        很简单的一道题目,经验丰富的前端一眼就能看出来这里有一个坑,知道三次输出的都是3,而一些缺乏经验的前端往往会认为是输出0 1 2(好吧,其实我曾经也是其中的一员,哈哈),那么到底是什么原因会让我们的想法跟实际有出入呢?原因就在于:因为所有这些函数拥有同一个作用域,这个属性中的循环计数器的值是最后一次所赋的值。下面来详细解释下:

        下面的两段js语句是等价的:

for(var i=0;i<3;i++) 等价于 var i;for(i=0;i<3;i++)

        在for循环中,我们看到的是每一个data[i]是一个函数,具体功能是输出 i 的值,然后这里只是函数的声明和定义,却并没有调用这个函数,当退出for循环的时候,此时的i的值为3(当i=3的时候退出for循环,i的值不再变化),然后通过data[0](),data[1](),data[2]()这里调用了函数,这个时候函数里面是要输出i的值,那么需要去寻找i的作用域,然而此时i的值变成了3,这就造成了缺乏经验的前端会有实际与理论的出入了,那么解决的办法是:

var data = [];
for(var i=0;i<3;i++){
    data[i] = (function(i){
        console.log(i);
    })(i);
}

        这里使用了立即执行函数,将在for循环中的i传进去,这个时候得到的i则是每次进入for循环中的i的值,从而正常得到了我们的0 1 2 的值。当然,我们不想直接就让它执行了这个函数,我们想要通过自己的调用,但是i的值又不会出现非预期的效果,那么这个时候可以考虑使用闭包,代码如下:

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]();

        这样我们就能自己调用函数,并且保证了i的值不会出现非预期的变化了(关于闭包,如果有不懂的童鞋,请网上自行查阅资料)

转载于:https://my.oschina.net/meichao/blog/516357

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值