HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Good way to write extend method of a contructor?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
extendmethodwaywritecontructorgood

Problem

I've been following along a blog post on JavaScript inheritance. I wanted to slightly adapt this and try to write something more like I've seen in Backbone (extend method). See I set about it, and run into problems. Then I came across this SO post. It was so much simpler. So after some minor tweaks to that I set about writing a way each extended constructor could have their own extend method (inherited from Base). This is what I have:

var Base = function(name){
    this.name = name;
}
Base.prototype.extend = function(new_constructor){
    //new_constructor.prototype = new this.constructor();
    new_constructor.prototype = Object.create(this.constructor.prototype);
    new_constructor.prototype.constructor = new_constructor;

    return new_constructor;
}

var Robot = Base.prototype.extend(function(name, material){
    Base.call(this, name)
    this.material = material
    this.type = 'robot';
});

var T1000 = Robot.prototype.extend(function(options){
    Robot.call(this, options.name, options.material)
    this.guns = options.guns;
    this.type = 'killer robot';
});

robot = new Robot("Boutros", "metal");
t1000 = new T1000({name: "Arnie", material:"flesh/metal", guns:3});

console.log(robot)
console.log(t1000)


Anyway seems to work, but I'm a little new to this. Can anyone suggest any limitations with this approach. Also, I'd like to move the [Constructor].call out of the new constructor function and into the extend function so this is handled automatically, not sure if I can. Would appreciate your feedback.

Btw, here is my jsFiddle

Solution

I think you cannot move parent constructor call out of child constructor. At least because you have different parameters, extend function cannot guess what kind of parameters it should pass.

But even if you standardize all constructors, you will have to make a "smart" constructor in Base class, that know about possible "sub-constructors". I don't think its a good idea ))

But what i would do - remove any mention of parent-class from children constructors'.

var Base = function(name){
    this.name = name;
}
Base.prototype.extend = function(new_constructor){
    //new_constructor.prototype = new this.constructor();
    new_constructor.prototype = Object.create(this.constructor.prototype);
    new_constructor.prototype.constructor = new_constructor;
    new_constructor.prototype.parentConstructor = this.constructor;

    return new_constructor;
}

var Robot = Base.prototype.extend(function(name, material){
    Robot.prototype.parentConstructor.call(this, name)
    this.material = material
    this.type = 'robot';
});

var T1000 = Robot.prototype.extend(function(options){
    T1000.prototype.parentConstructor.call(this, options.name, options.material)
    this.guns = options.guns;
    this.type = 'killer robot';
});

robot = new Robot("Boutros", "metal");
t1000 = new T1000({name: "Arnie", material:"flesh/metal", guns:3});

console.log(robot)
console.log(t1000)

Code Snippets

var Base = function(name){
    this.name = name;
}
Base.prototype.extend = function(new_constructor){
    //new_constructor.prototype = new this.constructor();
    new_constructor.prototype = Object.create(this.constructor.prototype);
    new_constructor.prototype.constructor = new_constructor;
    new_constructor.prototype.parentConstructor = this.constructor;

    return new_constructor;
}

var Robot = Base.prototype.extend(function(name, material){
    Robot.prototype.parentConstructor.call(this, name)
    this.material = material
    this.type = 'robot';
});

var T1000 = Robot.prototype.extend(function(options){
    T1000.prototype.parentConstructor.call(this, options.name, options.material)
    this.guns = options.guns;
    this.type = 'killer robot';
});

robot = new Robot("Boutros", "metal");
t1000 = new T1000({name: "Arnie", material:"flesh/metal", guns:3});

console.log(robot)
console.log(t1000)

Context

StackExchange Code Review Q#46254, answer score: 2

Revisions (0)

No revisions yet.