Reputation: 5586
I have an object:
function Shape(color, position, coordinates){
this.color = color;
this.position = position;
this.coordinates = coordinates;
this.shrink = function(){
reduce(coordinates);
};
};
And one of many objects with a 'is a' relationship to the previous object.
function Sphere(color, position, coordinates, radius){
this.radius = radius;
this.role = function(){
move(coordinates);
};
};
And a separate Draw function which draws the shapes
function draw(shape){
moveTo(shape.position);
setColor(shape.color);
sketch(shape.coordinates);
};
I know I should try use composition where possible but in some cases such as the one above, inheritance is a much more fitting model.
Without frameworks and as simply as possible how could I use prototypal inheritance or any other form to inherit the functionality and attributes of shape so I don't have to redefine them for every shape type I create and be able to pass arguments into the constructor of the inheriters object so they are passed to the object being inherited from.
EDIT
I searched the posts with similar titles and non of them provided examples regarding my specific situation, passing arguments in constructor and inheriting variables and functions. Also I find answer regarding this subject tend to present multiple options and I was looking for a more definitive answer on the standard approach (by way of example)
With regard to the so called definitive answer Performing inheritance in JavaScript I find that if I was to define all my attributes as described in prototype functions my script would be a mess, also it doesn't present what to do with arguments passed to the constructor.
Upvotes: 2
Views: 567
Reputation: 55678
I generally find that parasitic inheritance is the easiest option in JavaScript:
function Sphere(color, position, coordinates, radius){
var shape = new Shape(color, position, coordinates);
shape.radius = radius;
shape.role = function(){
move(coordinates);
};
return shape;
};
The big downside is that you don't get to use the prototype chain - attaching methods to Sphere.prototype
won't make them available on new Sphere
instances.
Upvotes: 1
Reputation: 31961
Javascript does not have any native construct to achieve this. However, there are utility libraries that help you achieve this.
If you're interested in doing this, take a look at Dean Edward's Base library:
http://dean.edwards.name/weblog/2006/03/base/
You can probably use this as is to achieve what you want. At any rate, I can recommend every javascript prorammer to to read that code and try to understand how it works - it will make you a better programmer.
A very simple solution that does not rely on inheritance at all and also solves the problem of passing in the arguments would be to use object literals as arguments. To assign you simply copy all of the fields from the object literal like so:
//copy instance variables from source to target
function copyInstanceVars(source, target){
var p,v;
for (p in source){
if (source.hasOwnProperty(p)) {
v = source[p];
target[p] = v;
}
}
return target;
}
//Shape, base class.
var Shape;
(Shape = function(config) {
copyInstanceVars(config, this); //copy instance variables from the config
}).prototype = { //class members go in the prototype
shrink: function(){
reduce(coordinates);
}
};
//Sphere, subclass of Shape
var Sphere;
(Sphere = function(config){
Shape.apply(this, arguments);
}).prototype = copyInstanceVars(Shape.prototype, { //inherit methods from Shape
role: function(){
move(coordinates);
};
});
Then, when instantiating the objects, you'd do:
var shape = new Shape({
color: "blue",
...,
coordinates: {x:10, y:20}
});
var sphere = new Sphere({
color: "blue",
...,
...,
radius: 10
});
So, in this case, the instance variables are simply those fields present in whatever you pass into the constructor, and the copyInstanceVars function takes care of this copy process. (the hasOwnProperty check in there ensures we're only grabbing instance variables).
This example also illustrates how to inherit methods by using that same copyInstanceVars function. But this time we apply it to the prototype of the constructor (because we "declared" the methods as instance variables on the prototype)
Upvotes: 1