我有一个计时器功能,每隔2秒弹出一个文本'hello,welcome' . 此外,我还有一个清除定时器间隔的功能,以便在第10秒停止弹出 .
当我使用clearInterval函数行时,弹出框显示停止
setTimeout(function() {clearInterval(x); },10000);
但是当我使用settimeout函数时,弹出框显示不会停止
setTimeout("clearInterval(x);",10000);
但是如果我使用settimeout函数通过直接定义内置函数来显示弹出窗口 setTimeout("alert('hello, welcome');",2000); // works properly
你能否解释为什么settimeout函数对上面两行的行为有所不同 . 请在下面找到我的代码 .
<html>
<head>
<script type='text/javascript' >
function testclear()
{
var x = setInterval("alert('hello, welcome');",2000);
setTimeout(function() { clearInterval(x); },10000);
// setTimeout("clearInterval(x);",10000);
}
</script>
</head>
<body>
<input id='txt' onchange='testclear()' />
</body>
</html>
4 回答
这是因为当您评估该字符串时,尚未正确捕获变量'x' . 它可能会指向
window.x
(而不是包含间隔计时器ID的本地变量) .虽然工作示例中的闭包已经捕获了正确的
x
.避免
eval
的另一个原因 .您的警报尚未出现此问题,因为它没有引用任何变量,但我建议您也将其更改为关闭(“函数”)表单 .
那是因为
x
是函数testclear()
的本地 . 当您将函数传递给setTimeout时,它将获得与其写入的范围相同的范围,因此将识别x
.传递字符串文字时,将对其进行评估,但范围将丢失 .
如果
x
将是全局变量,它也将"work",但这不是一个好习惯 .工作示例 Here 我已经自定义了您的代码,它工作正常 .
使x变量全局 .
var t= setTimeout(' clearInterval(x);' ,1501);
设置临时变量以捕获setTimeout,它遵循语义 .我相信当你为
setInterval
或setTimeout
的第一个参数指定一个字符串时,它将在特定的时间/间隔用eval
执行 . 因此,它在全球范围内运行 . 在您的情况下,x
在全局范围内不可用...它是testclear
函数内部的局部变量 . 将函数作为第一个参数传递给setInterval
或setTimeout
可以保护您最初使用的范围(在testclear
函数内) .或者,但不是优选的,我相信你可以做到这一点:
但请注意,在其他情况下(其他方法调用),此串联可能不同或不可能