Marty
Marty

Reputation: 39456

Extending/overriding in JavaScript?

I want to write a small game using JavaScript and <canvas> but first I want to nail the "correct" or at least common approach to working with Objects.

One topic I am having trouble understanding in particular is how I could implement overriding of method.

When I create an Object, I may have this:

function MyObject()
{
    var base = {};

    base.i = 0;
    base.update = function()
    {
        base.i ++;
    }

   return base;
}

Then when I create another Object that should start with the same members, I use this:

function AnotherObject()
{
    var base = new MyObject();

    base.j = 0;

    return base;
}

I want to add more content to AnotherObject.update() while still running the logic I have in MyObject.update(), but when I do this within AnotherObject():

base.update = function()
{
    j ++;
}

Then I of course lose the logic I added in MyObject.update().

How can I write AnotherObject.update() so that it also calls the original update() method defined by MyObject?

Upvotes: 0

Views: 81

Answers (4)

Simon Charette
Simon Charette

Reputation: 5116

First, I'd suggest you read this excellent excellent MDN article. It will enlighten you.

You can achieve subclassing this way:

function MyObject() {
  this.i = 0;
}

MyObject.prototype.update = function() {
  this.i++;
}

function AnotherObject() {
  MyObject.call(this);
  this.j = 0;
}

AnotherObject.prototype = new MyObject;

AnotherObject.prototype.constructor = AnotherObject;

AnotherObject.prototype.update = function() {
  MyObject.prototype.update.call(this);
  this.j++;
}

obj = new AnotherObject();
console.log(obj.i); //0
console.log(obj.j); //0

obj.update();
console.log(obj.i); //1
console.log(obj.j); //1

console.log(obj instanceof MyObject) //true
console.log(obj instanceof AnotherObject) //true

Upvotes: 2

Diode
Diode

Reputation: 25135

As others have suggested you should follow prototype based inheritance. That is the right way to do it.

But as a solution to what you have done so far you can do as shown below

function MyObject() {
    var base = {};
    base.i = 0;
    base.update = function () {
        this.i++;
    }
    base.show = function () {
        console.log("i is " + this.i);
    }
    return base;
}

function AnotherObject() {
    var base = new MyObject();
    base.j = 0;
    var update = base.update;  // proxy variable that refers to original `update`
    base.update = function () {
        update.call(this);  // invoke original `update`
        this.j++;
    }
    var show = base.show;  // proxy variable that refers to original `show`
    base.show = function () {
        show.call(this);   // invoke original `show`
        console.log("j is " + this.j);
    }
    return base;
}

var t = AnotherObject();
t.update();
t.show(); 

Upvotes: 0

pdizz
pdizz

Reputation: 4240

function MyObject() {
    this.value = 5;
}
MyObject.prototype.update = function() {
     this.value++;
}
Var newObject = new MyObject();
newObject.update =function() {
    value--;
}

Upvotes: 0

robrich
robrich

Reputation: 13205

+1 for zzzzBov's comment. You're using base when you should be using prototype. Not within the constructor function, but rather after the constructor function to further refine the class definition.

Upvotes: 0

Related Questions