📅  最后修改于: 2023-12-03 14:47:25.597000             🧑  作者: Mango
setTimeout
是 JavaScript 的一个重要函数,它用来延迟执行一个函数。在这篇文章中,我们将会介绍 setTimeout
的基本用法、一些常见的用例以及它可能的一些坑点。
setTimeout
接受两个参数:要执行的函数以及延迟的时间(以毫秒为单位)。以下是一个延迟一秒钟后将 "Hello, world!"
打印到控制台的示例:
setTimeout(function() {
console.log("Hello, world!");
}, 1000);
这里的第一个参数是一个匿名函数,第二个参数是指延迟的时间长度,单位是毫秒。
与 setTimeout
对应的,还有一个函数 clearTimeout
,用来取消一个已经通过 setTimeout
设置的延迟执行任务。以下是取消上述例子的代码:
var timeoutId = setTimeout(function() {
console.log("Hello, world!");
}, 1000);
clearTimeout(timeoutId);
这里,我们将 setTimeout
的返回值(一个数值)保存在 timeoutId
变量中,然后在需要取消它的时候调用 clearTimeout
并传入这个数值即可。
通过 setTimeout
可以方便地创建一个定时器,将在指定时间之后执行任务。下面的例子就是一个定时器,每隔一秒钟输出当前时间:
function displayTime() {
var now = new Date();
console.log(now.toLocaleTimeString());
}
setTimeout(function repeat() {
displayTime();
setTimeout(repeat, 1000);
}, 1000);
这里的匿名函数 repeat
将会周期性地调用自己,并且每隔一秒钟执行一次。注意,在这个例子中我们只调用了一次 setTimeout
因此是一个无限循环执行的定时器。
在一些场景下,我们希望某个函数的执行不会过于频繁。例如,在用户输入的时候搜索,我们希望当用户停止输入后再开始搜索。这时候,我们可以使用 setTimeout
来实现函数节流:
function search() {
// some search logic...
}
var timeoutId = null;
function delayedSearch() {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(search, 500);
}
document.querySelector("input").addEventListener("keyup", delayedSearch);
这个例子中,delayedSearch
函数通过 setTimeout
实现了一个延时执行的逻辑。每次触发 keyup
事件后,如果有之前的定时执行任务存在,则先取消它,然后重新设置一个新的延时任务,在 500 毫秒之后执行 search
函数。
通过 setTimeout
,我们可以控制动画的帧率和刷新间隔时间。例如,下面的例子中,我们将一个元素沿水平方向从左向右移动:
var element = document.querySelector(".animated");
var x = 0;
function animate() {
x += 10;
element.style.left = x + "px";
if (x < 500) {
setTimeout(animate, 50);
}
}
animate();
这个例子中,animate
函数将会被周期性地执行,每 50 毫秒一次。在这个函数中,我们不断地改变元素的 left
值,使得元素沿水平方向向右移动。当元素到达一定的位置(这里是 500 像素)之后,停止调用 setTimeout
。
this
值在使用 setTimeout
的时候,需要注意回调函数中的 this
指向。在下面的例子中,我们在一个对象上定义了一个方法,这个方法在 1 秒钟后被调用:
var obj = {
name: "object",
sayHello: function() {
console.log("Hello, " + this.name + "!");
}
};
setTimeout(obj.sayHello, 1000);
由于在这里使用了 obj.sayHello
,因此我们期望这个方法中的 this
应该是 obj
。但是实际上,这个函数的 this
值是 window
。
这是因为 setTimeout 中传递了一个函数引用,但是它没有指定 this
值,因此 this
的值会被默认绑定到全局对象上。实际上,传递给 setTimeout 的应该是一个函数调用表达式,例如:
setTimeout(function() {
obj.sayHello();
}, 1000);
在这个例子中,我们传递了一个匿名函数,而这个函数中又调用了 obj.sayHello 方法。这样的话,sayHello 中的 this 值就会被正确地绑定到 obj 上。
在不同的浏览器上,setTimeout
的延迟时间可能会有所不同。尤其当延迟时间很小时,这种差异表现得更加明显。并不是所有的浏览器都能正确地处理很小的延迟时间。因此,如果需要严格控制延迟时间,需要特别小心。
通过使用 setTimeout
,我们可以实现很多 JavaScript 应用场景中常见的逻辑。从定时器到函数节流,从动画控制到异步请求,都可以用 setTimeout
来实现。但是在使用的过程中,我们也需要特别小心 this
值的绑定和延迟时间的控制。