I want to validate that the approach I'm using is correct when it comes to extend a prototype - supposing "extend" is the right word.
This topic gets a lot of clones. I'm still trying to properly understand this topic...
The purpose is:
Here is the Parent prototype of my sandbox:
function Parent(){
}
Parent.prototype = {
"init":function(){
this.name = "anon";
},
"initWithParameters":function(parameters){
this.name = parameters.name ? parameters.name : "anon";
},
"talk": function(){
console.log('Parent is: ' + this.name);
}
}
Now the Child prototype - it adds a "position" property and redefines the behaviors:
function Child(){
Parent.call(this);
}
Child.prototype = new Parent;
Child.prototype.constructor = Child;
Child.prototype.init = function(){
Parent.prototype.call(this);
this.setPosition(0, 0);
}
Child.prototype.initWithParameters = function(parameters){
Parent.prototype.initWithParameters.call(this, parameters);
if(!this.position){
this.position = {x:0, y:0};
}
this.setPosition(parameters.pos.x, parameters.pos.y);
}
Child.prototype.setPosition = function(x, y){
this.position.x = x;
this.position.y = y;
}
Child.prototype.talk = function(){
console.log('Child is: ' + this.name + ' and location is: ' + this.position.x + ', ' + this.position.y);
}
Is this a good practice? Is there no shorthand to avoid writing "Child.prototype." when overriding a property (using a literal maybe, like the Parent prototype is written).
I know of J. Resig's Class/extend approach. But I'd rather use JavaScript as the prototypical language it is, not make it work as a "class-like behaving class-less OO language".
In general your approach will work but a better approach will be to replace:
Child.prototype = new Parent;
with:
Child.prototype = Object.create(Parent.prototype);
This way you don't need to call new Parent
, which is somewhat an anti-pattern. You could also define new properties directly as follows:
Child.prototype = Object.create(Parent.prototype, {
setPosition: {
value: function() {
//... etc
},
writable: true,
enumerable: true,
configurable: true
}
});
Hope this helps.