setInterval() 与 setTimeout()详解
setTimeout和都是 JavaScript 中用于设置定时器的函数,这个两个函数在开发中十分常用,理解并区分这两个函数是很有必要的
setInterval与 setTimeout详解
setTimeout 和 setInterval 都是 JavaScript 中用于设置定时器的函数。
setTimeout()
语法
setTimeout(fn, delay, param1, param2, /* … ,*/ paramN)
-
fn: 定时器到期后,将要执行的函数。
-
delay(可选): 定时器在执行指定的函数或代码之前应该等待的时间,单位是毫秒,省略后默认是0。非数字的延迟值将被静默强制转化为数字,但这个转化未发生意外,例如:
"1秒"最终被强制转换为数字0,因此,不要使用字符串来表示 delay值,而要始终使用数字。 -
param1, …,paramN:fn的附加参数,定时器到期,作为参数传递给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, …,argN:fn的附加参数,定时器到期,作为参数传递给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!"
setInterval 和 setTimeout更多用法:
setInterval: https://developer.mozilla.org/zh-CN/docs/Web/API/setInterval
setTimeout:https://developer.mozilla.org/zh-CN/docs/Web/API/setTimeout
更多推荐

所有评论(0)