[英]Why do I get a ReferenceError when using audio in setTimeout?
I want to schedule an audio play. 我想安排音频播放。 Why this code returns a ReferenceError for a?
为什么此代码返回a的ReferenceError?
function playSound()
{
var a = new Audio("mp3/win.mp3");
setTimeout("a.play('mp3/win.mp3');", 1000);
}
playSound();
Move a
variable definition to the global context: 将
a
变量定义为全球范围内:
var a = new Audio("mp3/win.mp3");
function playSound()
{
setTimeout("a.play('mp3/win.mp3');",1000);
}
playSound();
Or use function
notation instead of code
notation 或使用
function
符号代替code
符号
function playSound()
{
var a = new Audio("mp3/win.mp3");
setTimeout(function() {
a.play('mp3/win.mp3');
},1000);
}
playSound();
The cause of the issue, I think, is in the eval-like nature of setTimeout code
notation. 我认为,问题的原因在于setTimeout
code
符号的类似评估的性质。 Let's see what MDN says on setTimeout
(1) : 让我们看看MDN在
setTimeout
(1)上说了什么:
Passing a string instead of a function to setTimeout() suffers from the same hazards as using eval.
将字符串而不是函数传递给setTimeout()会遭受与使用eval相同的危害。
And then on eval
(2) : 然后在
eval
(2)上 :
If you use the eval function indirectly, by invoking it via a reference other than eval, as of ECMAScript 5 it works in the global scope rather than the local scope.
从ECMAScript 5开始,如果通过非eval的引用调用eval函数来间接使用eval函数,则它在全局范围而不是局部范围内工作。 This means, for instance, that function declarations create global functions, and that the code being evaluated doesn't have access to local variables within the scope where it's being called.
例如,这意味着函数声明将创建全局函数,并且所评估的代码无法访问被调用范围内的局部变量。
And setTimeout("a.play('mp3/win.mp3')", 1000)
is like an indirect eval
call. setTimeout("a.play('mp3/win.mp3')", 1000)
就像一个间接的eval
调用。
When you use the string notation on setTimeout
it's not being treated as if it was a function as you would imagine (since the first parameter is typically a function). 在
setTimeout
上使用字符串表示法时,不会像您想象的那样将其视为函数(因为第一个参数通常是函数)。 Instead it's treated as if it was a script that's being run whenever the amount of milliseconds has passed. 而是将其视为脚本,只要经过了毫秒的时间就在运行。
So it's as if it were adding: 就像添加了一样:
<script>a.play('mp3/win.mp3');</script>
Every 1000 milliseconds. 每1000毫秒。
Since a
is not global (its part of the function that does the setTimeout), then it can't see it hence the ReferenceError. 由于
a
不是全局的(它是执行setTimeout的函数的一部分),因此它看不到它,因此ReferenceError。
Don't use a string as the argument to setTimeout
, it's executed in the global scope, so it can't access local variables. 不要使用字符串作为
setTimeout
的参数,它在全局范围内执行,因此它无法访问局部变量。 Use a function argument. 使用函数参数。
function playSound()
{
var a = new Audio("mp3/win.mp3");
setTimeout(() => a.play('mp3/win.mp3'),1000);
}
playSound();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.