首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我在ReferenceError中使用音频时会得到一个setTimeout?

为什么我在ReferenceError中使用音频时会得到一个setTimeout?
EN

Stack Overflow用户
提问于 2017-11-02 00:06:18
回答 3查看 189关注 0票数 1

我想安排一部有声剧。为什么这段代码返回一个ReferenceError?

代码语言:javascript
复制
function playSound()
{
  var a = new Audio("mp3/win.mp3");
  setTimeout("a.play('mp3/win.mp3');", 1000);
}
playSound();
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-02 00:09:55

a变量定义移动到全局上下文:

代码语言:javascript
复制
var a = new Audio("mp3/win.mp3");
function playSound()
{
  setTimeout("a.play('mp3/win.mp3');",1000);
}
playSound();

或者用function符号代替code表示法。

代码语言:javascript
复制
function playSound()
{
  var a = new Audio("mp3/win.mp3");
  setTimeout(function() {
    a.play('mp3/win.mp3');
  },1000);
}
playSound();

我认为,这一问题的原因在于setTimeout code表示法的类似年代的性质。让我们看看MDN在setTimeout (1)上说了些什么

将一个字符串而不是一个函数传递给setTimeout(),会遇到与使用eval相同的危险。

然后在eval (2)

如果您间接地使用eval函数,通过引用(而不是ECMAScript 5)调用它,它将在全局范围内工作,而不是在本地范围内工作。例如,这意味着函数声明创建了全局函数,而要计算的代码在调用它的作用域中没有访问局部变量的权限。

setTimeout("a.play('mp3/win.mp3')", 1000)就像一个间接的eval调用。

票数 2
EN

Stack Overflow用户

发布于 2017-11-02 00:27:42

当您在setTimeout上使用字符串表示法时,它并不像您想象的那样被视为一个函数(因为第一个参数通常是一个函数)。相反,当毫秒数超过时,它就会被当作是一个正在运行的脚本。

所以就好像是在添加:

代码语言:javascript
复制
<script>a.play('mp3/win.mp3');</script>

每1000毫秒一次。

因为a不是全局的(它在函数中执行setTimeout的部分),所以它不能看到它,因此就不能看到ReferenceError。

票数 0
EN

Stack Overflow用户

发布于 2017-11-02 00:31:17

不要使用字符串作为setTimeout的参数,它是在全局范围内执行的,因此不能访问局部变量。使用函数参数。

代码语言:javascript
复制
function playSound()
{
    var a = new Audio("mp3/win.mp3");
    setTimeout(() => a.play('mp3/win.mp3'),1000);
}
playSound();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47065526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档