简体   繁体   English

在setTimeout中使用音频时,为什么会出现ReferenceError?

[英]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.

相关问题 为什么我在这里得到“setTimeout 不是函数”? - Why do I get “setTimeout is not a function” here? 为什么我得到 setTimeout(...) is not a function? - Why do I get setTimeout(...) is not a function? 为什么我会得到这个JavaScript ReferenceError - Why do I get this JavaScript ReferenceError 为什么我会收到“ReferenceError:未定义测试” - Why do I get “ReferenceError: test is not defined” 直接从成员函数访问成员变量时,为什么会出现ReferenceError? - Why do I get a ReferenceError when accessing member variables from a member function directly? 为什么在bloxk范围之外调用函数时没有收到ReferenceError? - Why I do not get ReferenceError when calling a function outside a bloxk scope? 为什么会出现Uncaught ReferenceError:未定义scrollToM? - Why do I get Uncaught ReferenceError: scrollToM is not defined? 为什么会收到“未捕获的ReferenceError:未定义$(匿名函数)” - Why do I get an “Uncaught ReferenceError: $ is not defined (anonymous function)” 为什么我会收到此错误:“未捕获的 ReferenceError:未定义 value1”? - Why do I get this error: “Uncaught ReferenceError: value1 is not defined”? 使用setTimeout()时,如何使用call()设置`this`的值? - How do I use call() to set the value of `this` when using setTimeout()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM