这是我参与8月更文挑战的第18天,活动详情查看8月更文挑战
前言
setTimeout 和 setInterval,相信大家都是经常用,或多或少都会用一些,但是可能会有很多同学,并不是特别地了解相关的比较深入的东西,仅仅停留在使用层面而已。今天我们就来深入了解 setTimeout 和 setInterval 吧。
setTimeout 的用法
mdn 的说明:
WindowOrWorkerGlobalScope
混合的setTimeout()
方法设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。
先来回顾下 setTimeout 怎么使用,我们看下下面的代码:
因为 setTimeout 方法是浏览器 window 对象提供的,所以我们可以把 window 给去掉。
setTimeout(function() {
console.log('追梦玩家');
}, 1000);
// 等价于
/* window.setTimeout(function() { console.log('追梦玩家'); }, 1000); */
结合上面 mdn 文档的说明,其实 setTimeout 也可以说是一个延时器,也就是说第二个参数,决定了多少毫秒之后,再去执行一个函数或者指定的一段代码。
setInterval 的用法
mdn 的说明:
WindowOrWorkerGlobalScope
的setInterval()
方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。
同样的,我们来回顾下 setInterval 是怎样使用的,我们看下:
setInterval (function() {
console.log('追梦玩家');
}, 1000);
上面代码,其实就是每隔 1000 毫秒,然后去执行对应的函数,打印 “追梦玩家”。
第一个参数可以是字符串
相信大家平时使用 setTimeout 的话,第一个参数都是传函数。传字符串,这种形式,大家使用的应该比较少,那我们来了解一下:
setTimeout("console.log('追梦玩家');", 1000);
这种方式,见得比较少,为什么不用呢?
在
delay
毫秒之后编译和执行字符串 (使用该语法是不推荐的, 原因和使用eval()
一样,有安全风险)。
其实如果第一个参数是字符串的话,相当于是执行 eval() 方法来执行 code。
setTimeout 的返回值
注:这里举例的是 setTimeout,对于 setInterval 也同样适用的。 setTimeout 的返回值 timeroutID,是一个正整数,表示定时器的编号。
var timer1 = setTimeout(function() {
console.log('追梦玩家');
}, 1000);
var timer2 = setTimeout(function() {
console.log('追梦玩家');
}, 1000);
var timer3 = setTimeout(function() {
console.log('追梦玩家');
}, 1000);
console.log(typeof timer1);
console.log(timer1, timer2, timer3);
输出结果,可以看下图
有个问题,那我们怎么取消定时器呢?
其实就是使用到上面执行方法的返回值 timeroutID,可以传递给 clearTimeout 来取消定时器。
var timer1 = setTimeout(function() {
console.log('追梦玩家');
}, 1000);
clearTimeout(timer1);
在控制台输入这个代码,并且执行,你会发现控制台并没有打印出”追梦玩家”。说明已经取消掉定时器了。
注:使用 setInterval 方法,要取消定时器,可以使用 clearInterval 方法。使用跟 clearTimeout 一样。
参数传参问题
那使用 setTimeout 方法的时候,我们想要传参,应该怎么做呢?
我们先来尝试一下:
var timer1 = setTimeout(function (...args) {
console.log('args', args);
}, 1000, 1, 2, 3, 4, 5, 6);
上面这个方式,大家觉得怎么样?看起来是可以实现传参了。那有没有更优雅的方式呢?有的。
function test(...args) {
console.log('args', args);
}
var timer1 = setTimeout(function () {
test(1, 2, 3, 4, 5, 6);
}, 1000);
其实就是在 setTimeout 的第一个函数里面,放入一个 test 函数并且执行,传入对应的参数。
this 指向
我们先来了解下什么是隐式丢失?
隐式丢失是指被隐式绑定的函数丢失绑定对象,这种情况容易出错却又常见,为什么呢?因为 JavaScript
中函数可以作为参数,也可以作为返回值被四处传播,传着传着就丢了 this
指向,被传的晕头转向了。
我们看个例子:
var obj = {
a: function() {
console.log(this);
}
}
var test = obj.a;
test();
输出结果是 window 对象,如果是直接执行 obj.a 这个方法,不进行赋值操作的话,输出结果是 obj 对象,其实就是在赋值的过程中,发生了隐式丢失。
使用 setTimeout/setInterval 方法,也会出现隐式丢失。
var obj = {
a: function() {
console.log(this);
}
};
setTimeout(obj.a, 1000);
输出结果也是 window 对象,那怎么解决这个 this 指向的问题呢?
有两种方式:
- 使用 bind 方法将 obj.a 方法的 this 绑定到 obj 上
- 将 obj.a 函数放置在定时器中的匿名函数中执行
具体代码,可以看下面
// 方式1
setTimeout(obj.a.bind(obj), 1000);
// 方式2
setTimeout(function() {
obj.a();
}, 1000);
时间间隔
HTML5 标准规定
- setTimeout 的最短时间间隔是4毫秒
- setInterval 的最短间隔时间是10毫秒, 也就是说,小于10毫秒的时间间隔会被调整到10毫秒
后台模式
大多数电脑显示器的刷新频率是60HZ,大概相当于每秒钟重绘60次。因此,最平滑的动画效的最佳循环间隔是1000ms/60,约等于16.6ms。
为了节电,对于那些不处于当前窗口的页面,浏览器会将时间间隔扩大到1000毫秒。
另外,如果笔记本电脑处于电池供电状态,Chrome和IE9以上的版本,会将时间间隔切换到系统定时器,大约是16.6毫秒。
写到最后
本文主要让大家理解了 setTimeout 和 setInterval 的相关知识:
- 第一个参数可以是字符串
- setTimeout 的返回值
- 参数传参问题
- this 指向
- 时间间隔
文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你或者喜欢,欢迎点赞和关注。
今天的文章深入理解 setTimeout 与 setInterval分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/14756.html