正确的Javascript继承

时间:2011-02-13 16:49:48

标签: javascript inheritance

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

Sprite

3 个答案:

答案 0 :(得分:6)

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

function Moveable(x, y) {
  Sprite.call(this, x, y);
}

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

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

Moveable.prototype = makePrototype(Sprite);

这使用虚拟构造函数来创建与Sprite共享相同原型的对象,由于这是所有JavaScript关心的问题,Moveable的实例被视为instanceof Sprite

这不像你要求的那样“简短易读”,但唯一的另一种选择是完全跳过原型并直接在构造函数中分配成员。

编辑:正如@Raynos指出的那样,您还需要设置constructor属性(默认情况下由JavaScript完成,但在您重置{{1}后会立即丢失}):

Moveable.prototype

答案 1 :(得分:6)

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

function Moveable(x, y) {
    Sprite.call(this, x, y);
}

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

如果你构造一个临时的空对象,你可以绕过实例化你的基类。看起来很复杂,但通常用作辅助函数(就像在Google Closure Library goog.inherits method中我或多或少地复制了它):

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);

答案 2 :(得分:1)

将函数视为两个部分:构造函数和原型对象。取两个这样的函数类并将它们混合在一起。混合对象很简单,诀窍是混合构造函数。

var Sprite = function(x, y, w, h){
   console.log("Sprite constr:", x, y, w, h);
}

var Moveable = function(x, y, w, h){
   console.log("Moveable constr:", x, y, w, h);
}

var extend = function(class1, class2){
   // here we make a new function that calls the two constructors. 
   // This is the "function mix" 
   var f = function(){
      class1.prototype.constructor.apply(this, arguments);
      class2.prototype.constructor.apply(this, arguments);
   }
   // now mix the prototypes
   f.prototype = library.objectmix(class1.prototype, class2.prototype);
   return f;
}

var MoveableSprite = extend(Sprite, Moveable);