【问题标题】:EaselJS: Can somebody explain the inheritance pattern used in demos?EaselJS:有人可以解释演示中使用的继承模式吗?
【发布时间】:2013-08-02 03:43:40
【问题描述】:

我正在使用 EaselJS 创建一个游戏,我想知道是否有人可以解释演示文件中使用的继承模式是如何工作的。具体来说,我正在查看以下文件:https://github.com/CreateJS/EaselJS/blob/master/examples/assets/Ship.js

在第 7 行,Ship 的原型被设置为 createjs.container()...的实例。

var p = Ship.prototype = new createjs.Container();

然后在第 28 行,存储了对原始构造函数的引用:

p.Container_initialize = p.initialize;  //unique to avoid overiding base class

最后,Ship 对象在第 30 行初始化

p.initialize = function () {
    this.Container_initialize();

我正试图围绕这种模式展开思考,因为它与我过去遇到的任何情况都不同。有人可以向我解释为什么你想使用一个类的实例作为新类的原型吗?也许只是给我指出一个解释这种模式的链接?非常感谢这里的任何帮助......我意识到这个问题有点含糊。

【问题讨论】:

  • 这是一个常见的模式,在这里查看教程developer.mozilla.org/en-US/docs/Web/JavaScript/…
  • 谢谢,这几乎回答了我的问题。具体来说:“专门化的类通常称为子类,而另一个类通常称为父类。在 JavaScript 中,您可以通过将父类的实例分配给子类,然后对其进行专门化来实现这一点。在现代浏览器中,您可以也可以使用 Object.create 来实现继承。”
  • 要了解这一切,最好的办法是查看 @EaselJS 的 Typescript 定义文件。

标签: javascript easeljs


【解决方案1】:

我正试图围绕这种模式展开思考,因为它与我过去遇到的任何情况都不同。

我也没有。它并没有太大的魔力,但他的结构绝对不常见。请参阅Correct javascript inheritance 了解正确的模式。

有人可以向我解释一下为什么要使用类的实例作为新类的原型吗?

你没有。您想使用从父类的原型对象继承的对象。 Unfortunately many people use new ParConstructor for that - 如果构造函数为空,则效果很好。如果构造函数确实创建了实例属性或有其他副作用,则可能会引起麻烦。不过,大多数人似乎并没有注意到或关心这一点。

这个模式的解释?

function Ship() {
    this.initialize();
}

这只是在新实例上调用initialize 方法(构造函数中的this)。我没有看到将初始化代码直接放在构造函数中的任何好处,但尽管如此。

var p = Ship.prototype = new createjs.Container();

如上所述,这是设置原型链从Container“类”继承方法。它可能会进行不必要的实例初始化,因此应将其替换为 Object.create 调用。它会为原型创建一个快捷方式变量。

// constructor:
p.Container_initialize = p.initialize;    //unique to avoid overiding base class

在这里,创建了对父构造函数的显式引用。 p 上的 initialize 属性继承Container 原型,现在它成为具有描述性名称的 p 对象的自己的属性.这是必要的,因为……

p.initialize = function () {
    this.Container_initialize();
    … // property init stuff

...这里在原型对象上声明了一个自己的initialize 方法,隐藏了继承的方法。尽管如此,现在可以使用该专用属性在当前实例上调用“超级”初始化代码。这样做是quitecommon,但不是这样用的方法。相反,call 通常用于将父构造函数应用于子实例。

更好(至少,更熟悉):

function Ship() {
    this.initialize();
}

var super_p = createjs.Container.prototype,
    p = Ship.prototype = Object.create(super_p);

p.initialize = function() {
    super_p.initialize.call(this);
    … // property init stuff

或者,或者没有initialize

function Ship() {
    createjs.Container.call(this);
    … // property init stuff
}
Ship.prototype = Object.create(createjs.Container.prototype);

【讨论】:

  • 我会投票赞成,但我需要更多的声望点才能这样做。感谢您的深入解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
  • 2012-05-29
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多