setInterval() 与 setTimeout()详解


setTimeoutsetInterval 都是 JavaScript 中用于设置定时器的函数。

setTimeout()

语法

setTimeout(fn, delay, param1, param2, /* … ,*/ paramN)
  • fn: 定时器到期后,将要执行的函数。

  • delay(可选): 定时器在执行指定的函数或代码之前应该等待的时间,单位是毫秒,省略后默认是0非数字的延迟值将被静默强制转化为数字,但这个转化未发生意外,例如:"1秒"最终被强制转换为数字 0,因此,不要使用字符串来表示 delay值,而要始终使用数字

  • param1, …, paramNfn的附加参数,定时器到期,作为参数传递给 fn 指定的函数。

清除定时器clearTimeout() 消除定时器。

let a = setTimeout(fn, 1000) // setTimeout会返回一个timeoutID(一个正数),表示定时器的编号
clearTimeout(a) // 消除定时器

setTimeout()异步函数,意味着计时器函数将不会暂停函数栈中其他函数的执行。

this问题

this 指向问题的原因

setTimeout() 函数会在指定的时间间隔之后执行指定的代码。这个代码块是在一个独立的执行环境中执行的,而不是在调用 setTimeout() 的函数的执行环境中执行的。

意味着,在 setTimeout() 中执行的代码块中,this 关键字的值可能与调用 setTimeout() 的函数中的 this 值不同。默认情况下this 将引用全局对象 window(在浏览器环境中)或 global 对象(在 Node.js 等环境中)

const myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
  console.log(arguments.length > 0 ? this[sProperty] : this);
};
myArray.myMethod(); // 输出 "zero,one,two"
setTimeout(myArray.myMethod, 1.0 * 1000); // 在 1 秒后输出 "[object Window]"

解决办法

使用包装函数

一、使用Obj对象

// 假设有一个对象 obj,它有一个方法 showMessage
const myArray = {
  arry: ["zero", "one", "two"],
  myMethod:  function (sProperty) {
      console.log(arguments.length > 0 ? this.arry[sProperty] : this.arry);
  };
};
// 使用包装函数确保在 setTimeout 中的上下文是 obj
function wrapper() {
  myArray.myMethod();
}
// 调用 setTimeout 并传递包装函数
setTimeout(wrapper, 1000); // 输出: "zero,one,two"

二、匿名函数

setTimeout(function () {
  myArray.myMethod();
}, 2.0 * 1000); // 在 2 秒后输出 "zero,one,two"

匿名函数和Obj对象充当了包装函数的角色,myArray.myMethod()作为普通的函数调用,而不是作为对象方法。这样,即使在 setTimeout() 执行时,执行环境发生了变化,myArray.myMethod() 仍然能够正确地在 myArray 上下文中执行。

三、箭头函数

setTimeout(() => {
  myArray.myMethod();
}, 2.0 * 1000); // 在 2 秒后输出 "zero,one,two"

箭头函数会捕获其父作用域的 this 值。这样可以确保在 setTimeout() 中执行的代码中,this 的值与调用 setTimeout() 的函数中的 this 值一致。

使用Bind()

const myArray = ["zero", "one", "two"];
const myBoundMethod = function (sProperty) {
  console.log(arguments.length > 0 ? this[sProperty] : this);
}.bind(myArray);
setTimeout(myBoundMethod, 1.0 * 1000); // 由于绑定问题,还是在 1 秒后输出 "zero,one,two"

setInterval()

语法

var intervalID = setInterval(fn, delay, arg1, arg2, ...);
  • fn: 定时器到期后,将要执行的函数。

  • delay(可选): 定时器在执行指定的函数或代码之前应该等待的时间,单位是毫秒省略后默认是0非数字的延迟值将被静默强制转化为数字,但这个转化未发生意外,例如:"1秒"最终被强制转换为数字 0,因此,不要使用字符串来表示 delay值,而要始终使用数字

  • arg1, …, argNfn的附加参数,定时器到期,作为参数传递给 fn 指定的函数。

清除定时器clearInterval() 消除定时器,用法与clearTimeout() 一致。

同样setInterval()也存在与setTimeout一致的this问题。

setInterval() 与 setTimeout() 的区别

触发方式

  • setTimeout:用于在指定的时间间隔后执行一次指定的代码。
  • setInterval:用于每隔指定的时间间隔重复执行指定的代码。

执行次数

  • setTimeout 只会执行一次指定的代码,然后就会停止。
  • setInterval重复执行指定的代码,直到被取消(通过 clearInterval 函数)或者页面被关闭。

利用setTimeout 实现 setlnterval

function customSetInterval(callback, interval) {
    function loop() {
        callback();
        setTimeout(loop, interval); // 在回调函数执行完后再次设置定时器
    }
    loop(); // 第一次调用
}
customSetInterval(function() {
    console.log('Hello, World!');
}, 1000); // 每隔一秒输出一次 "Hello, World!"

setIntervalsetTimeout更多用法:

setInterval: https://developer.mozilla.org/zh-CN/docs/Web/API/setInterval

setTimeout:https://developer.mozilla.org/zh-CN/docs/Web/API/setTimeout

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值