您当前位于:
JavaScript高级 ——> 原生JavaScript setInterval与setTimeout参数详解
原生JavaScript setInterval与setTimeout参数详解
2015/05/05 11:24:40
|
作者:HTML5学堂(码匠)
|
分类:JavaScript高级
|
关键词:setInterval,setTimeout
setInterval和setTimeout参数剖析
HTML5学堂:在平时使用的时候很少去注意计时器的参数问题,因为比较常用的是函数和时间这两个参数,很少遇到传入的是字符串类型的参数。本文给大家讲解的是当计时器传入的参数是字符串类型的时候,会出现什么问题?
当定时器第一个参数是函数名
-
// 存储定时器返回的ID
-
var timer = null;
-
-
function show() {
-
console.log("梦幻雪冰、独行冰海");
-
}
-
-
timer = setInterval(show, 1000);
-
console.log(timer);
-
-
// 当 setInterval 被调用时,它会返回一个 ID 标识并且计划在将来大约 1000 ms后调用 show函数。 show函数间隔1000ms多次执行。
注意:基于 JavaScript 引擎的计时策略,以及本质上的单线程运行方式,所以其它代码的运行可能会阻塞此线程。因此没法确保函数会在 setInterval 指定的时刻被调用(拿上面的那个例子来说,不能保证间隔1000ms调用一次)。
函数名与函数调用的区别
setInterval 的第一个参数是函数对象(函数的地址),一个常犯的错误是这样的 setInterval (show(), 1000),这里回调函数是 show 的返回值,而不是show本身。大部分情况下,这是一个潜在的错误。如果函数返回 undefined,setInterval 也不会报错。
当定时器第一个参数是匿名函数
-
// 存储定时器返回的ID
-
var timer = null;
-
-
timer = setInterval(function() {
-
console.log("梦幻雪冰、独行冰海");
-
}, 1000);
-
console.log(timer);
当定时器第一个参数是JavaScript代码串
setTimeout 和 setInterval 都可以接受字符串作为它们的第一个参数,但是这个特性绝对不要使用,因为它在内部使用了 eval(绝对不要使用 eval,任何使用它的代码都会在它的工作方式,性能和安全性方面受到质疑)。
-
function show() {
-
// 将会被调用
-
console.log("梦幻雪冰");
-
}
-
-
function test() {
-
function show() {
-
// 不会被调用
-
console.log("独行冰海");
-
}
-
setTimeout('show()', 2000);
-
}
-
test();
结果:输出的是 梦幻雪冰
解析:由于 eval 在这种情况下不是被直接调用(因为eval的作用域是当前执行的作用域,setTimeout的作用域是在全局,所以eval不是在函数test里面执行,而是在全局中执行),因此传递到 setTimeout 的字符串会自动在全局作用域中执行;因此,上面的回调函数使用的不是定义在 test 作用域中的局部变量 show。简单的理解,只能调用全局中声明的函数。
欢迎沟通交流~HTML5学堂
回调函数传递参数使用字符串形式
-
function test(a, b) {
-
console.log(a + "和" + b);
-
}
-
-
// 不推荐大家这样做,因为这样定时器就会使用到eval
-
setTimeout('test(1, 2)', 2000);
使用匿名函数完成相同功能
-
function test(a, b) {
-
console.log(a + "和" + b);
-
}
-
-
// 可以使用匿名函数完成相同功能
-
setTimeout(function() {
-
test(1, 88);
-
}, 2000);
还有另外一种解决办法,但是在IE9以及IE9以下不支持。
-
function test(a, b) {
-
console.log(a + "和" + b);
-
}
-
-
setTimeout(test, 2000, 1, 2);
资料:
定时器第一个参数会在全局作用域中执行,因此函数内的 'this'将会指向这个全局对象
-
function test(a, b) {
-
// this执行的是window
-
console.log(this);
-
}
-
-
setTimeout(test, 2000);
总结:
不要使用字符串作为 setTimeout 或 setInterval 函数的参数,当需要向回调函数中传递参数时,我们可以用匿名函数的,在匿名函数内部执行回调函数。另外,尽量避免使用 setInterval 函数,从而避免可能导致的回调函数堆积现象。
欢迎沟通交流~HTML5学堂
阅读:1025