我想安排音频播放。为什么这段代码会为?
返回一个ReferenceErrorfunction playSound()
{
var a = new Audio("mp3/win.mp3");
setTimeout("a.play('mp3/win.mp3');", 1000);
}
playSound();
答案 0 :(得分:2)
将a
变量定义移动到全局上下文:
var a = new Audio("mp3/win.mp3");
function playSound()
{
setTimeout("a.play('mp3/win.mp3');",1000);
}
playSound();
或使用function
表示法而不是code
表示法
function playSound()
{
var a = new Audio("mp3/win.mp3");
setTimeout(function() {
a.play('mp3/win.mp3');
},1000);
}
playSound();
我认为问题的原因与setTimeout code
符号的eval类似。让我们看看MDN在setTimeout
(1)上说了什么:
将字符串而不是函数传递给setTimeout()会受到影响 与使用eval相同的危险。
然后在eval
(2):
如果你间接使用eval函数,可以通过a调用它 除了eval之外的参考,从ECMAScript 5开始,它在全球范围内起作用 范围而不是本地范围。这意味着,例如,那 函数声明创建全局函数,代码是 评估无法访问范围内的局部变量 在哪里被召唤。
setTimeout("a.play('mp3/win.mp3')", 1000)
就像是间接的eval
电话。
答案 1 :(得分:0)
当你在setTimeout
上使用字符串表示法时,它并没有像你想象的那样被视为一个函数(因为第一个参数通常是一个函数)。相反,它被视为一个脚本,只要经过了毫秒数就会运行。
所以它好像在添加:
<script>a.play('mp3/win.mp3');</script>
每1000毫秒。
由于a
不是全局的(它是执行setTimeout的函数的一部分),因此它无法看到它,因此引用了ReferenceError。
答案 2 :(得分:0)
不要使用字符串作为setTimeout
的参数,它在全局范围内执行,因此它无法访问局部变量。使用函数参数。
function playSound()
{
var a = new Audio("mp3/win.mp3");
setTimeout(() => a.play('mp3/win.mp3'),1000);
}
playSound();