首页 > web前端 > js教程 > Settimeout JavaScript函数:指南示例

Settimeout JavaScript函数:指南示例

尊渡假赌尊渡假赌尊渡假赌
发布: 2025-02-10 14:34:10
原创
782 人浏览过

setTimeout JavaScript Function: Guide with Examples

JavaScript 的 setTimeout 函数详解:实现延迟执行

setTimeout 是 JavaScript 中的原生函数,用于在指定延迟(毫秒)后调用函数或执行代码片段。这在许多场景下非常有用,例如:在用户浏览页面一段时间后显示弹出窗口,或在移除元素悬停效果前添加短暂延迟(防止误操作)。

关键要点:

  • JavaScript 的 setTimeout 函数允许在指定毫秒数的延迟后执行函数或代码片段,这对于诸如在一定浏览时间后显示弹出窗口之类的任务非常有用。
  • setTimeout 接受函数引用作为第一个参数,该引用可以是函数名称、引用函数的变量或匿名函数。它也可以执行代码字符串,但不建议这样做,因为这样会降低可读性、安全性并降低速度。
  • 可以使用匿名函数作为第一个参数,将参数传递给 setTimeout 执行的回调函数。但是,在延迟之后列出参数的替代方法与 IE9 及以下版本不兼容。
  • setTimeout 执行的代码中,this 的值在与调用它的函数不同的执行上下文中运行,这在 this 关键字的上下文很重要时可能会导致问题。这可以使用 bind、库函数或箭头函数来解决。
  • setTimeout 的返回值是一个数字 ID,可用于结合 clearTimeout 函数取消计时器。

setTimeout 使用示例

以下代码块显示了一个简单的示例,该示例将在 2 秒(2000 毫秒)的超时后将消息打印到控制台:

function greet() {
  console.log('Howdy!');
}
setTimeout(greet, 2000);
登录后复制
登录后复制
登录后复制
登录后复制

为了更详细地演示这个概念,下面的演示在点击按钮两秒钟后显示一个弹出窗口:(请访问 CodePen 查看演示)

语法

根据 MDN 文档,setTimeout 的语法如下:

const timeoutID = setTimeout(code);
const timeoutID = setTimeout(code, delay);

const timeoutID = setTimeout(functionRef);
const timeoutID = setTimeout(functionRef, delay);
const timeoutID = setTimeout(functionRef, delay[, arg1, arg2, /* … ,*/ argN])
登录后复制
登录后复制
登录后复制

其中:

  • timeoutID 是一个数字 ID,可与 clearTimeout 结合使用以取消计时器。
  • scope 指的是 Window 接口或 WorkerGlobalScope 接口。
  • functionRef 是计时器到期后要执行的函数。
  • code 是一种替代语法,允许您包含字符串而不是函数,该字符串在计时器到期时进行编译和执行。
  • delay 是函数调用应延迟的毫秒数。如果省略,则默认为 0。
  • arg1, ..., argN 是传递给 functionRef 指定的函数的其他参数。

注意:方括号 [] 表示可选参数。

setTimeoutwindow.setTimeout

您会注意到,有时语法中包含 window.setTimeout。这是为什么呢?

在浏览器中运行代码时,scope 将指代全局 window 对象。setTimeoutwindow.setTimeout 指的是同一个函数,唯一的区别是,在第二个语句中,我们将 setTimeout 方法作为 window 对象的属性来引用。

在我看来,这增加了复杂性,而好处却微乎其微。如果您定义了另一种 setTimeout 方法,该方法将在作用域链中优先找到并返回,那么您可能还有更大的问题需要担心。

在本教程中,我将省略 window,但最终,您选择哪种语法取决于您自己。

setTimeout 方法的使用示例

setTimeout 方法接受函数引用作为第一个参数。

这可以是函数的名称:

function greet() {
  console.log('Howdy!');
}
setTimeout(greet, 2000);
登录后复制
登录后复制
登录后复制
登录后复制

引用函数的变量(函数表达式):

const timeoutID = setTimeout(code);
const timeoutID = setTimeout(code, delay);

const timeoutID = setTimeout(functionRef);
const timeoutID = setTimeout(functionRef, delay);
const timeoutID = setTimeout(functionRef, delay[, arg1, arg2, /* … ,*/ argN])
登录后复制
登录后复制
登录后复制

或者匿名函数:

function greet() {
  alert('Howdy!');
}
setTimeout(greet, 2000);
登录后复制
登录后复制

如上所述,也可以将代码字符串传递给 setTimeout 以供其执行:

const greet = function() {
  alert('Howdy!');
};
setTimeout(greet, 2000);
登录后复制
登录后复制

但是,由于以下原因,不建议这样做:

  • 难以阅读(因此难以维护和/或调试)。
  • 它使用隐式 eval,这是一种潜在的安全风险。
  • 它比替代方案慢,因为它必须调用 JS 解释器。

传递参数给 setTimeout

在基本场景中,首选的跨浏览器方法是使用匿名函数作为第一个参数将参数传递给 setTimeout 执行的回调函数。

在下面的示例中,我们从 animals 数组中选择一个随机动物,并将此随机动物作为参数传递给 makeTalk 函数。然后,setTimeout 以一秒的延迟执行 makeTalk 函数:

setTimeout(() => { alert('Howdy!'); }, 2000);
登录后复制
登录后复制

注意:我使用了一个常规函数(getRandom)从数组中返回一个随机元素。也可以使用箭头函数将其编写为函数表达式:

setTimeout('alert("Howdy!");', 2000);
登录后复制
登录后复制

我们将在下一节介绍箭头函数。这里有一个包含上述代码的 CodePen(您需要打开控制台才能查看输出)。

替代方法

从文章顶部的语法可以看出,传递参数给 setTimeout 执行的回调函数还有第二种方法。这涉及在延迟之后列出任何参数。

参考我们之前的示例,这将给我们:

function makeTalk(animal) {
  const noises = {
    cat: 'purr',
    dog: 'woof',
    cow: 'moo',
    pig: 'oink',
  }

  console.log(`A ${animal} goes ${noises[animal]}.`);
}

function getRandom(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

const animals = ['cat', 'dog', 'cow', 'pig'];
const randomAnimal = getRandom(animals);

setTimeout(() => {
  makeTalk(randomAnimal);
}, 1000);
登录后复制
登录后复制

不幸的是,这在 IE9 或以下版本中不起作用,其中参数作为 undefined 传递。如果您不幸需要支持 IE9,则 MDN 上提供了一个 polyfill。

this 关键字的问题

setTimeout 执行的代码在其与调用它的函数不同的执行上下文中运行。当 this 关键字的上下文很重要时,这会成为问题:

function greet() {
  console.log('Howdy!');
}
setTimeout(greet, 2000);
登录后复制
登录后复制
登录后复制
登录后复制

此输出的原因是,在第一个示例中,this 指向 dog 对象,而在第二个示例中,this 指向全局 window 对象(它没有 sound 属性)。

为了解决这个问题,有各种方法……

显式设置 this 的值

您可以使用 bind 来实现,bind 方法创建一个新函数,当调用该函数时,其 this 关键字将设置为提供的值(在本例中为 dog 对象)。这将给我们:

const timeoutID = setTimeout(code);
const timeoutID = setTimeout(code, delay);

const timeoutID = setTimeout(functionRef);
const timeoutID = setTimeout(functionRef, delay);
const timeoutID = setTimeout(functionRef, delay[, arg1, arg2, /* … ,*/ argN])
登录后复制
登录后复制
登录后复制

使用库

许多库都带有内置函数来解决此问题。例如,jQuery 的 jQuery.proxy() 方法。它接受一个函数并返回一个新函数,该函数将始终具有特定上下文。在本例中,那将是:

function greet() {
  alert('Howdy!');
}
setTimeout(greet, 2000);
登录后复制
登录后复制

setTimeout 中使用箭头函数

箭头函数是在 ES6 中引入的。它们比常规函数的语法短得多:

const greet = function() {
  alert('Howdy!');
};
setTimeout(greet, 2000);
登录后复制
登录后复制

当然,您可以将它们与 setTimeout 一起使用,但是需要注意一点——箭头函数没有自己的 this 值。相反,它们使用封闭词法上下文的 this 值。

使用常规函数:

setTimeout(() => { alert('Howdy!'); }, 2000);
登录后复制
登录后复制

使用箭头函数:

setTimeout('alert("Howdy!");', 2000);
登录后复制
登录后复制

在第二个示例中,this 指向全局 window 对象(同样,它没有 sound 属性)。

这在将箭头函数与 setTimeout 一起使用时可能会让我们陷入困境。之前我们看到了如何为 setTimeout 中调用的函数提供正确的 this 值:

function makeTalk(animal) {
  const noises = {
    cat: 'purr',
    dog: 'woof',
    cow: 'moo',
    pig: 'oink',
  }

  console.log(`A ${animal} goes ${noises[animal]}.`);
}

function getRandom(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

const animals = ['cat', 'dog', 'cow', 'pig'];
const randomAnimal = getRandom(animals);

setTimeout(() => {
  makeTalk(randomAnimal);
}, 1000);
登录后复制
登录后复制

当在引入的方法中使用箭头函数时,这将不起作用,因为箭头函数没有它自己的 this 值。该方法仍将记录 undefined

使用箭头函数和 setTimeout 编写更简洁的代码

但是,因为箭头函数没有自己的 this 值,所以它也可以为我们带来优势。

考虑这样的代码:

const getRandom = arr => arr[Math.floor(Math.random() * arr.length)];
登录后复制

可以使用箭头函数更简洁地重写它:

setTimeout(makeTalk, 1000, randomAnimal);
登录后复制

如果您想了解箭头函数的入门知识,请阅读“ES6 箭头函数:JavaScript 中简洁的语法”。

取消计时器

正如我们在文章开头了解到的那样,setTimeout 的返回值是一个数字 ID,可与 clearTimeout 函数结合使用以取消计时器:

function greet() {
  console.log('Howdy!');
}
setTimeout(greet, 2000);
登录后复制
登录后复制
登录后复制
登录后复制

让我们看看它的实际效果。在下面的 Pen 中,如果您点击“开始倒计时”按钮,倒计时将开始。如果倒计时完成,小猫就赢了。但是,如果您按下“停止倒计时”按钮,计时器将被停止并重置。(如果您在倒计时达到零时没有看到很酷的效果,请使用嵌入底部右侧的按钮重新运行 Pen。)

总结

在本文中,我演示了如何使用 setTimeout 来延迟函数的执行。我还展示了如何将参数传递给 setTimeout,如何在其回调函数内部维护 this 值,以及如何取消计时器。

setTimeout JavaScript 函数的常见问题解答

  • setTimeout 在 JavaScript 中是什么?

    setTimeout 是 JavaScript 中的内置函数,允许您在指定的延迟(以毫秒为单位)后安排函数或代码段的执行。

  • setTimeout 如何工作?

    当您调用 setTimeout 函数时,您需要提供两个参数:要执行的函数或代码,以及以毫秒为单位的延迟。提供的函数/代码将添加到队列中,并在指定的延迟后,它将从队列移动到调用堆栈以执行。

  • 使用 setTimeout 的替代方法有哪些?

    是的,有替代方法,例如 setInterval,它会以指定的间隔重复执行函数,以及较新的 requestAnimationFrame,它用于更流畅的动画和更好的浏览器性能。

  • 什么时候不应该使用 setTimeout

    setTimeout 是用于在 JavaScript 中调度异步代码执行的有用工具,但在某些情况下它可能不是最佳选择。对于精确的动画或游戏,您应该使用 requestAnimationFrame。您不应该嵌套多个 setTimeout 调用;最好使用 Promise 或异步模式。setTimeout 对小于 10 毫秒的延迟不准确;请考虑替代方案。如果您正在构建实时应用程序(如在线多人游戏或金融交易平台),请选择实时技术,如 WebSockets。大型 CPU 密集型任务可能会阻塞事件循环;如果需要,请使用 Web Workers。

  • 我可以取消 setTimeout 操作吗?

    是的,您可以使用 clearTimeout 函数取消计划的超时。它将 setTimeout 返回的超时 ID 作为参数。例如:const timeoutId = setTimeout(myFunction, 1000); clearTimeout(timeoutId);

  • setTimeoutsetInterval 之间的区别是什么?

    setTimeout 将函数安排在指定的延迟后运行一次,而 setInterval 将函数安排在指定的间隔重复运行,直到它被取消或程序停止。

  • 我可以使用 setTimeout 的最小延迟值是多少?

    最小延迟值为 0,这意味着该函数安排在当前线程完成但处理任何挂起的事件之前执行。但是,计时器的实际粒度因不同的浏览器和环境而异。某些环境可能不支持小于 10 毫秒的延迟。

  • setTimeout 在 Node.js 中是什么?

    setTimeout 是 Node.js 的内置函数,用于将给定函数或代码块的执行延迟指定的毫秒数。

  • 如何在 Node.js 中使用 setTimeout

    您可以按如下方式使用 setTimeout 函数:setTimeout(callback, delay); 其中 callback 是您希望在指定的毫秒延迟后执行的函数。

  • 在 Node.js 中使用 setTimeout 的最佳实践有哪些?

    一些最佳实践包括使用命名函数作为回调函数,优雅地处理错误,并了解事件循环的行为以避免意外延迟或阻塞。此外,请考虑使用 setImmediate 在下一个事件循环周期中立即执行。

(请注意,由于输入文本中包含 CodePen 的链接,我无法直接在输出中呈现 CodePen 的内容。您需要访问文中提供的链接来查看 CodePen 演示。)

以上是Settimeout JavaScript函数:指南示例的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板