【面试小题】闭包模拟块级作用域

题目

已知数组["a","b","c","d","e"],编写代码,每过 1 秒打印一下数组中的值。

答案

ES5

var arr = ["a", "b", "c", "d", "e"];
for (var i = 0; i < arr.length; i++) {
  (function(j) {
    var item = arr[j];
    setTimeout(function() {
      console.log(item);
    }, 1000 * (i + 1));
  })(i);
}
复制代码

ES6

利用 ES6 中 let 块级作用域的特性。

var arr = ["a", "b", "c", "d", "e"];
for (let i = 0; i < arr.length; i++) {
  const item = arr[i]; // let | const
  setTimeout(() => {
    console.log(item);
  }, 1000 * (i + 1));
}
复制代码

思考

看题目很容易意识到这是在考块级作用域,考点主要是 ES5 里没有块级作用域,但可以用闭包来模拟块级作用域

一个普通的循环

for (var i = 0; i < 5; i++) {
  console.log(i);
}
// 0 1 2 3 4
复制代码

加上 setTimeout

for (var i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i);
  }, 0);
}
// 5 5 5 5 5
复制代码

setTimeout属于注册事件,绑定的事件是当前事件队列(同步事件)执行完毕后再执行,因此等到执行console.log的时候,i 已经变成 5 了。

再来一题

思考以下代码的打印结果。

var test = function() {
  var arr = [];
  for (var i = 0; i < 3; i++) {
    arr[i] = function() {
      return i * i;
    };
  }
  return arr;
};

var a = test();

a[1](); // 9
a[2](); // 9
复制代码

执行 test()的结果是一个数组,里面每一个元素都是function,在实际调用的时候,i 的值已经是 3 了,因此结果都是 9。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值