I have a few problem with JavaScript inheritance and prototype. All the research I have made, in stackoverflow/google lead me to use the prototype of my class, but that's the point I want to avoid. I know JavaScript is not conceived that way but I'm sure it's possible, I'm just stuck.
I have two classes (or more maybe later). One is the base, that will be the mother of all, I want it to have all the basics attributes and method (like a basic OO). My objects are for geometry.
function EnvObject(){
this.position = {x: 0, y: 0};
this.velocity = {x: 0, y: 0};
this.mass = 0; // kg
this.restitution = 0; // Restitution
this.A = 0;
this.Cd = 0; // Drag force
function init(_x, _y, _mass, _restitution)
{
blabla
};
};
function oCircle()
{
function foo(){}
function bar(){}
}
function oSquare()
{
function foo(){}
function bar(){}
}
The main class provide all the information for my classes, like square or circle... Extend it with prototype will lead to big problem and a great thing, Methods are well shared (that's cool), but my attributes are also shared so when I change it in my Square class, the attributes will also change in Circle (which is a bad things)
I know the main solution is to not provides an interface for attributes, and place them only in the Square/Circle classes, but it's not very clean (I mean I write same attributes twice or more).
My main goal is to create a new class with 2 or more other class, without them sharing anything or maybe just few method? And eventually writing clean code? :)
So I've tried many scripts... All of them use that technique. Or maybe I'm just wrong which is probably true.
Also I know that class doesn't exist in JS, it's just a big function. Is it better to write object like this? I tend to like it much, because using function is a bit confusion in my opinion. Maybe inheritance is much easier in this way?
var envObject = {
position: {x, y}
}
var oCircle = {
foo: function(){}
}
4 Answers 4
You've probably got issues with the nested objects (position, velocity). You will need to create the subobjects for each distinct instance separately.
Also I know that class doesn't exist in JS, it's just a big function. Is it better to write object like this?
No, not "better", it's just different. Instead of using constructor functions that are called with new and set properties on this, you can just use functions that return plain objects - less confusing.
Maybe inheritance is much easier in this way?
Not the prototypical inheritance that JavaScript uses. Also, you might want to have a look at this answer on how "classes" work in JavaScript.
1 Comment
Use a new Instance of the prototype object:
function oCircle() {
function Circle() {
this.foo = function(){};
}
Circle.prototype = new EnvObject();
return new Circle();
};
Now, whenever you call new oCircle(), a new instance of EnvObject is used. This is what you expect of class-based inheritance.
6 Comments
EnvObject instance? Don't understand what you mean with "expert". Maybe that pattern is useful in different situations, but not here.Have you tried to apply the combination of prototype chaining and constructor stealing?
function SuperType(){
this.prop1 = // some value
this.prop2 = // some other value
}
SuperType.prototype.function1 = function(){
};
function SubTypeA(){
SuperType.call(this); // add inherited properties to this instance
this.subTypeProperty1 = ...
}
SubTypeA.prototype = new SuperType();
SubTypeA.prototype.subTypeFunction1 = function(){
}
Each subtype will have its own inherited properties.
4 Comments
The Best Approach ... (I've seen)
This is a good starting point -- we use the combination of Constructor-Stealing & Prototypical-Inheritance (noted by #ppoliani above):
function SuperType() {
this.super = 'type';
}
SuperType.prototype = { m: function () { } };
function C() {
SuperType.call(this);
this.key = 'value';
};
C.prototype = (new (function () {
$.extend(this, new SuperType());
this.some = 'thing';
})());
var c = new C();
console.log(c);
However, this could use some tuning up -- for instance, the C.prototype object (uses new so that we can use this -- which is good) extends this with new SuperType() and the method is added to this and not C.prototype -- not good. It also uses a non-native $.extend function -- not good.
Of course, the heavy use of inheritance can be a very undesirable methodology. Complex-Deep-Inheritance-Hierarchies often lead to extreme entropy in your Class Architecture. If your hierarchies are complex, deep architectures become maintenance, portability, and adaptivity nightmares. If this is the case, begin implementing The Decorator Pattern.
This is rather a demonstrative answer here to give readers better tools for manipulating the inheritance chain.
Hope this helps.
init,fooandbarfunctions do there? How and where do you use them?