setTimeout与闭包

本文探讨了JavaScript中的setTimeout函数,解释了它的工作原理,包括返回的唯一ID在清除定时器中的作用。此外,文章讨论了当延迟时间为0时setTimeout的行为,并通过实例展示了其并不立即执行。最后,文章深入讲解了setTimeout与闭包的关系,如何利用闭包解决异步执行中的变量问题,以确保按预期顺序打印数字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、关于 setTimeout

setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。

比如在1秒后打印出字母"a":

setTimeout('console.log("a")', 1000);

执行效果图:

120503_WAfl_3796163.png

我们看到执行setTimeout后,出现了一个数字 1309 ,这个数字是当前的setTimeout执行后所返回的一个唯一ID。

那么,这个唯一的ID的作用是什么呢?(请看下列代码)

var timer = setTimeout(function() {
  console.log("a");
}, 1000);

clearTimeout(timer);

上述代码是我们,特别是前端小伙伴,再熟悉不过的了!
分成两块去看的话,那就是:

1. 设定定时器;

2. 清除定时器。

变量 timer 保存了当前这个 setTimeout 执行后的返回值,clearTimeout 接收了参数 timer ,就可以阻止setTimeout 的运行。

二、当 setTimeout 的延迟执行时间为 0

setTimeout的用法:

setTimeout(code / function, millseconds, param1, param2, . . .);

其中第一个参数是必要的,millseconds 为可选参数,默认为 0。

那么我们需要思考一个问题,

setTimeout(/* codes . . */, 1000);

延迟时间设为 1000,意味着1秒后执行。

那么,

setTimeout(/* codes . . */);

// 或者

setTimeout(/* codes . . */, 0);

是否就意味着一定会立即执行?

这个,我们用一个例子来验证下:

setTimeout(function() { console.log('setTimeout') } );

function a() {
  console.log('函数 a 被执行!');
}

function b() {
  console.log('函数 b 被执行!');
}

a();
b();

执行结果:

123948_Lvqa_3796163.png

如上图所示,setTimeout 的参数 millseconds 设为 0 或为默认值,并不会使其立即执行,而是按照“先入先出”的原则,在当前任务队列中的事件或者同步任务完成后,在予以执行。

三、setTimeout 与 闭包

在 MDN 中,闭包被定义为:函数和声明该函数的词法环境的组合。即:可以获取其他函数内部变量的函数。
这里需要加深理解的概念是“词法环境”。

关于 setTimeout 与 闭包,这里用一个例子加以说明。

利用 setTimeout 将 1、2、3三个数字,间隔一秒予以打印。

按照思路大致可以写成:

for (var i = 1; i <= 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000 * i);
}

可能大家已经预料出,这段代码并不会打印出1、2、3,而是:

133039_UPnE_3796163.png

因为,根据 setTimeout 是在调用栈清空后才被执行的特点,在 setTimeout 执行前 i 的值已经变为 4 了,所以打印结果为 3 个 4。

那么,如何实现我们预期的效果?
利用闭包,将每个 i 的值保存在闭包中来给 setTimeout 访问:

for (var i = 1; i <= 3; i++) {
  setTimeout((function(i) {
    return function() {
      console.log(i);
    };
  })(i), 1000 * i);
}

// 或者

for (var i = 1; i <= 3; i++) {
  (function(i) {
    setTimeout('console.log(' + i + ')', 1000 * i);
  })(i);
}

效果如下:

133248_5Khc_3796163.png

转载于:https://my.oschina.net/u/3796163/blog/1634505

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值