【问题标题】:Inheritance in JavaScript with require.js: Illegal invocation使用 require.js 在 JavaScript 中继承:非法调用
【发布时间】:2013-04-05 19:46:02
【问题描述】:

我遇到了 require.js 和原型继承的问题。这是我的模块:

define([], (function() {
  "use strict";
  var Player = function() {
    console.log("Constructor of the Player Object");
    this.audioObject = new Audio();        
  };
  Player.prototype = new Audio();
  return Player;
})); // define

然后我尝试以这种方式使用音频对象的播放方法:

define(["jquery", "player"], (function($, Player) {
  "use strict";
  /**
  *  The controls for the player
  **/ 
  var Controls = function(player) {
    $(".play").click(function() {
      console.log("play");
      player.play();
    });
  };
  return Controls;
})); // define

点击按钮时,Chrome 会抛出错误: 未捕获的 TypeError:非法调用

我已经尝试了几个小时,在这里阅读了类似的问题,但其中大多数与 jQuery 有关,我认为这不是问题所在。 (我尝试自己定义一个名为 Player.prototype.play() 的方法,效果很好,但我认为这不是重写所有方法的最佳方法)

【问题讨论】:

    标签: javascript google-chrome inheritance requirejs


    【解决方案1】:

    这可能是因为Audio 具有一些隐藏的“幕后”属性,这些属性在实例化新的Player 时不会从原型中复制。

    当您调用 player.play() 时,play 期望在 Audio 实例上运行,但它在 Player 实例上运行。从理论上讲,这里应该没有问题,因为Player 应该与Audio 相同,因为它的原型是Audio 实例。但是,Audio 是一个宿主对象,这意味着它不需要按照普通 JavaScript 对象的规则来播放。

    也就是说,您为什么还要为您的Player 原型使用​​Audio 实例?除了容易出现奇怪的行为(正如您现在所观察到的)之外,这似乎完全没有必要,因为您已经在 audioObject 属性中持有一个 Audio 对象。

    我不完全了解您的设计,但为什么不使用audioObject,例如,在这里调用player.audioObject.play()

    【讨论】:

    • 感谢您的回答。我这样做的原因是因为我理解 JS 中的继承是如何工作的。我以为我会从继承的对象中获取所有方法。我试过你的方法,但它导致另一个错误:不允许加载本地资源:*链接到文件*
    • 好的,现在我解决了这个问题并使用了一些代码,最后在我的播放器的构造函数中使用了 this.prototype = new Audio() 并调用了 play( ) 与 player.prototype.play() (这是你的建议) - 非常感谢你对我的帮助很大,我现在终于可以继续了。
    • @Envious 您知道吗,像这样使用prototype 可能会使阅读您的代码的人感到困惑——他们可能会认为Playerinstance 是某种类型的构造函数。我绝对同意您使用这样的属性,但建议您将其命名为不同的名称。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    相关资源
    最近更新 更多