最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Proper Javascript inheritance - Stack Overflow

programmeradmin3浏览0评论

I am wondering whether it is possible to inherit constructor in javascript. In the following example, I'd like the Moveable to assign x and y arguments to this.x and this.y respectivelly, as I defined in Sprite. Also, what would be the best way (but still short and readable) to define the prototype without creating the instation of ancestor? It would be best to assign it in the class itself, not in the outside scope as I it is now:

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

I am wondering whether it is possible to inherit constructor in javascript. In the following example, I'd like the Moveable to assign x and y arguments to this.x and this.y respectivelly, as I defined in Sprite. Also, what would be the best way (but still short and readable) to define the prototype without creating the instation of ancestor? It would be best to assign it in the class itself, not in the outside scope as I it is now:

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();
Share Improve this question asked Feb 13, 2011 at 16:49 Mikulas DiteMikulas Dite 7,9419 gold badges61 silver badges103 bronze badges 2
  • 4 Proper inheritance Doesn't exist. – Raynos Commented Feb 13, 2011 at 17:18
  • 1 @Raynos Thanks, that's quite forting :) – Mikulas Dite Commented Feb 13, 2011 at 17:34
Add a ment  | 

3 Answers 3

Reset to default 6

The standard way to call a superclass constructor is using Function.call:

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

As for the prototype, you can do something like this to chain the prototype without creating an instance of the superclass:

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

Moveable.prototype = makePrototype(Sprite);

This uses a dummy constructor to create an object that shares the same prototype as Sprite, and since that's all JavaScript cares about, instances of Moveable are considered instanceof Sprite.

This isn't "short and readable" as you asked for, but the only other choice is to entirely skip prototypes and assign members directly within the constructor.

Edit: As @Raynos points out, you also want to set the constructor property (which is done by default by JavaScript but is lost as soon as you reset Moveable.prototype):

Moveable.prototype.constructor = Moveable;

You'd call the parent constructor like this:

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

I'm afraid there's no short way of setting up the inheritance if you want to use pseudo-classical inheritance, and no way of doing it inside the scope of the constructor function.

You can get around instantiating your base class though, if you construct a temporary empty object. Looks plicated but is monly used as a helper function (like in the Google Closure Library goog.inherits method from where I more or less copied this):

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

Think of a function as two pieces: the constructor function and the prototype object. Take two of these function classes and mix them together. Mixing the objects are simple enough, the trick is to mix the constructors.

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);
发布评论

评论列表(0)

  1. 暂无评论