views:

33

answers:

1

I don't seem to be able to overwrite class methods correctly, using the following code ...

function core() {
    console.log( "CORE CONSTRUCTOR CALLED" );
}

core.prototype.output = function() {
    return 'CORE';
}

function sub1() {
    console.log( "SUB 1 CONSTRUCTOR CALLED" );
    this.core();
}

sub1.prototype = core.prototype;
sub1.prototype.constructor = sub1;
sub1.prototype.core = core;

sub1.prototype.output = function() {
    return 'SUB 1';
}

function sub2() {
    console.log( "SUB 2 CONSTRUCTOR CALLED" );
    this.core();
}

sub2.prototype = core.prototype;
sub2.prototype.constructor = sub2;
sub2.prototype.core = core;

sub2.prototype.output = function() {
    return 'SUB 2';
}

var oCore = new core();
var oSub1 = new sub1();
var oSub2 = new sub2();

console.log( oCore.output() );
console.log( oSub1.output() );
console.log( oSub2.output() );

... I get the following output ...

CORE CONSTRUCTOR CALLED
SUB 1 CONSTRUCTOR CALLED
CORE CONSTRUCTOR CALLED
SUB 2 CONSTRUCTOR CALLED
CORE CONSTRUCTOR CALLED
SUB 2
SUB 2
SUB 2

What am I doing wrong?

+4  A: 

The problem is... when you are issuing the line:

sub2.prototype = core.prototype;

You are using the SAME prototype on sub2 as core, thus when you call .output() from ANY of the classes, the function at core.prototype.output is the sub2 version as it is the last one defined. Remember, object assignments happen by reference.

To copy the object you would commonly see:

sub2.prototype = new core();
sub2.prototype.core = core;

Or - if you want to avoid calling the constructor, you could use jQuery's $.extend(sub1.prototype, core.prototype); to copy the core prototype. If you don't have jQuery, this is about the same:

sub2.prototype = {};
for (var method in core.prototype) sub2.prototype[method] = core.prototype[method];
sub2.prototype.constructor = core;
sub2.prototype.core = core;
gnarf
Not using JQuery for this (purposefully trying to avoid tying the code to a JS framework) but the bottom example worked perfectly. Thankyou.
michael