Js的setTimeout没有每秒显示递增数

原创
小哥 3年前 (2022-11-14) 阅读数 35 #大杂烩

还有一些关于函数和闭包的立即执行的知识, 我先编码。

function abs() {
  for (var i = 0; i < 10; ++i) {
    setTimeout(() => {
      console.log(i);
    }, i * 1000);
  }
}

你认为上面的代码将执行什么, 应每秒执行正常预期。1~10的数字
但实际上, 上述代码每秒执行一次。10

这是为什么?
因为setTimeout回调在循环结束时执行,因此每次都会输出。10

第一种方法, 使用立即执行功能

function abs() {
  for (var i = 0; i < 10; ++i) {
    ((j) => {
      setTimeout(() => {
        console.log(j);
      }, i * 1000);
    })(i);
  }
}

原因 : 在迭代内使用立即执行功能会为每个迭代都生成一个新的作用域, 使延迟函数在每次迭代中关闭新作用域的回调,每个作用域都包含一个变量,该变量具有正确的值供我们访问。

第二种方法, 改为let声明

思考: 我们在使用立即执行功能的时候创建一个新的作用域才可以, 所以我们需要每个迭代的范围, let声明可以劫持块范围并在此块范围内声明变量!!!

function abs() {
  for (let i = 0; i < 10; ++i) {
    setTimeout(() => {
      console.log(i);
    }, i * 1000);
  }
}

原因 : for循环的头部let该声明还有一项特殊法案, 此行为表示变量在循环期间、每次迭代中声明了多次。每个后续迭代都使用上一次迭代结束时的值初始化该变量。

这就是解决方案

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门