4
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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)
\$\endgroup\$
1
\$\begingroup\$

I usually evaluate OO frameworks by asking 4 questions:

  • Does instanceof still work ? -> Yes, good
  • Do you introduce new properties causing potential naming clashes -> No, good
  • Can parameters easily be provided to the constructors -> Yes, good
  • Can I easily have properties in .prototype -> Yes, good

This is one of the better OO approaches I have seen on CodeReview.

I would not create a new custom property parentConstructor the parent constructor call, instead I would want to try to build a closure that calls both the parent constructor and the passed constructor. This means you would need to have deep thoughts about parameters.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.