正确的Javascript继承

Mik*_*ite 6 javascript inheritance

我想知道是否可以在javascript中继承构造函数.在下面的例子中,我想要Moveable分配xy参数this.xthis.y各自,如我所定义的那样Sprite.此外,在没有创建祖先的情况下定义原型的最佳方式(但仍然简短且可读)是什么?最好将它分配给类本身,而不是像现在这样在外部范围中分配:

function Sprite(x, y) {
    this.x = x ? x : 0;
    this.y = y ? y : 0;     
    this.getPos = function() {
        return {
            x: this.x,
            y: this.y
        };
    };
}

function Moveable(x, y) {

}
Moveable.prototype = new Sprite();
Run Code Online (Sandbox Code Playgroud)

cas*_*nca 6

调用超类构造函数的标准方法是使用Function.call:

function Moveable(x, y) {
  Sprite.call(this, x, y);
}
Run Code Online (Sandbox Code Playgroud)

至于原型,你可以做这样的事情来链接原型而不创建超类的实例:

function makePrototype(superclass) {
  function f() { }
  f.prototype = superclass.prototype;
  return new f();
}

Moveable.prototype = makePrototype(Sprite);
Run Code Online (Sandbox Code Playgroud)

这使用虚拟构造函数来创建一个共享相同原型的对象,Sprite因为这是所有JavaScript关心的,Moveable所以考虑了实例instanceof Sprite.

这不是你所要求的"简短和可读",但唯一的另一种选择是完全跳过原型并直接在构造函数中分配成员.

编辑:正如@Raynos指出的那样,你也想设置constructor属性(默认情况下由JavaScript完成,但是一旦你重置就会丢失Moveable.prototype):

Moveable.prototype.constructor = Moveable;
Run Code Online (Sandbox Code Playgroud)

  • 你忘了设置`prototype.constructor`属性了! (2认同)

mey*_*tee 6

你可以像这样调用父构造函数:

function Moveable(x, y) {
    Sprite.call(this, x, y);
}
Run Code Online (Sandbox Code Playgroud)

如果你想使用伪经典继承,我担心没有简短的方法来设置继承,并且在构造函数的范围内无法做到这一点.

如果你构造一个临时的空对象,你可以绕过实例化你的基类.看起来很复杂,但通常用作辅助函数(就像在谷歌闭包库goog.inherits方法,我或多或少复制了这个):

var inherits = function(childConstructor, parentConstructor) {
  function tempConstructor() {};
  tempConstructor.prototype = parentConstructor.prototype;
  childConstructor.prototype = new tempConstructor();
  childConstructor.prototype.constructor = childConstructor;
};

inherits(Moveable, Sprite);

// instantiating Moveable will call the parent constructor
var m = new Moveable(1,1);
Run Code Online (Sandbox Code Playgroud)