2

My situation is that I am working on a Canvas game using Box2DWeb, so I have a class called Sprite that draws an image to the Canvas, I now want to create a PhysicsSprite class that inherits methods and properties from Sprite.

My Sprite class (Sprite.js):

Sprite = function (position, dimension, image) {

  this.Position = position;
  this.Dimension = dimension;
  if (image)
    this.Image = image;
  ...

  this.Draw = function (g) {
    ...
  }
  ...
};

And I am setting the prototype in PhysicsSprite (PhysicsSprite.js) like so:

PhysicsSprite = function(position, dimension, world) {

    this.prototype = new Sprite(position, dimension, undefined);
    //alert(this.prototype.Position.X)

    var body = CreateBody();
    this.GetBody = function () { return body; }

    this.Draw = function (g) {
        ...  
    }

    function CreateBody () {
          ...
    }
};

Note the alert(this.prototype.Position.X), which does alert me of the position, but if I change the code to this.Position.X, I get an error, and similarly, if I have an instance of PhysicsSprite, I have to explicitly call the prototype.

This lead me to think that I haven't set the Object's prototype, merely created a property called prototype, and set that to a new Sprite.

If someone could help me, and explain what I am doing wrong, that would be much appreciated. I am dyslexic, so I always misspell variables, which is frustrating, so that was the first thing I looked for, but everything looks fine to me.

Cheran Shunmugavel
  • 8,319
  • 1
  • 33
  • 40
  • You are right. I recommend to have a look at the MDN documentation for examples: https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_constructor_prototype and https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited. This question might help as well: http://stackoverflow.com/questions/7944880/js-confusion-about-inheritance – Felix Kling May 06 '12 at 15:46

3 Answers3

3

This lead me to think that I haven't set the Object's prototype, merely created a property called prototype, and set that to a new Sprite.

That's right. Also, you are not making use of the function's prototype at all, since you assign each function directly to the instance (this.Draw = function() ...) instead of the prototype.


In JavaScript you have something called constructor functions. Every function called with the new operator is a constructor function.

When a function is called that way (new SomeFunc()), a new object is created (lets call it an isntance) which inherits from the object referenced by SomeFunc.prototype and this instance is available inside that function via this.

Now, inheritance basically comes down to having a prototype (SomeFunc.prototype) which instead of being an (nearly) empty object (the default), inherits from another function's prototype.

Example:

function A(name) {
    // `this` refers to a new instance
    // lets set some properties:
    this.name = name;
}

// all "class" methods should be assigned to the prototype
A.prototype.getName = function() {
    return this.name;
};


// lets create a child "class"
function B(name, place) {
    // we have to call the parents constructor with the current instance
    // and the arguments we want to pass on.
    // this is like `super(name)` in Java or `A.__init__(self, name)` in Python 
    // (or `super(B, self).__init__(name)` in Python)
    A.call(this, name);
    this.place = place;
}

// here we connect A's prototype with B's prototype in a way that they
// stay independent 
inherits(B, A);

// B's "class" methods
B.prototype.getPlace = function() {
    return this.place;
};

// now we can do
var b = new B('SomeName', 'SomePlace');
alert(b.getName());
alert(b.getPlace());

This is how inherits could look like (this implementation is used by the Google Closure library):

function inherits(Child, Parent) {
    var Tmp = function() {};
    Tmp.prototype = Parent.prototype;
    Child.prototype = new Tmp();
    Child.prototype.constructor = Child;
}

You see that Child.prototype refers to an instance of Tmp. But Tmp's prototype is the same as Parent's prototype. That means, the instance returned by new Tmp() inherits from Parent's prototype, and since this instance is the prototype of Child, all instances of Child will inherit from Parent.prototype as well.

With ECMAScript 5, this can be simplified to

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

but it's essentially the same. It creates a new object which inherits from Parent.prototype.


Further reading:

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
1

Change

this.prototype = new Sprite(position, dimension, undefined);

to

Sprite.apply(this, position, dimension, undefined);

You are right, before the change, you are assigning an instance of object to the "prototype" property.

The prototype is a property of the constructor function, not an object instance - i.e. you can access prototype by PhysicsSprite.prototype, but not this.prototype or x.prototype (where x = new PhysicsSprite()).

Krizz
  • 11,362
  • 1
  • 30
  • 43
0

JavaScript is a very different bird than Java, though they're often mistaken for each other because they both share { and }. :D

A typical JavaScript class:

function Sprite(a,b) {
    // These are per instance
    this.a = a;
    this.b = b;
}
Sprite.prototype = {
    // These are per class, all instances share them
    Draw: function (g) {
        // ...
    }
};

... and inheritance in JavaScript is very weird.

robrich
  • 13,017
  • 7
  • 36
  • 63