Reputation: 2476
UPDATE
Since I made this question, a lot of water has gone under the river, I have switch to use module pattern and CommonJS file format + Browserify and stop trying to make Javascript be more like an OOP language. I have embraced the Javascript Prototypal Inheritance and Object.create
and I my life is now better than ever!, yes almost feeling like I joined a new Religion
, sorry a religion
... no "new" for me anymore in JS.
The rest of the question is just history...
I have being playing around with OOP for a while in javascript.
Honestly the feeling I have is that most of the time true OOP is not needed. What I was used to do in other languages with OOP, could be done with functions and closures in javascript most of the time.
Also to mimic the OOP approach there are tons of ways to enable it either making it by hand or using a tiny library found out there.
I wanted to give it a try to OOP but all the solutions I found, seemed to me no that simple, some requesting me to add a init method or during initialization they were doing special inspection of the the functions to know if they need to be override. While that is clever it seemed a bit excessive for simple creating an object from a Class.
So I came with this solution:
UPDATE: this an experiment, not intended to replace any brilliant exiting library or to be used in production
var Nexus = function() {}; // helper function to avoid create an instance of the child class
Object._extend = function(child, parent) {
var base = Nexus.prototype = parent.prototype;
child.prototype = new Nexus();
var cp = child.prototype;
cp.constructor = child;
child._parent = base;
};
/* THIS THEN IS USED LIKE THIS */
var Person = function (name) {
this.name = name;
console.log('Person constructor');
};
$.extend(Person.prototype, {
walk : function () {
console.log(this.name + ' is Walking!!');
}
});
var Student = function () {
// call the base class constructor
Student._parent.constructor.apply(this, arguments);
console.log('Student Constructor');
}
Object._extend(Student, Person);
$.extend(Student.prototype, {
walk : function () {
console.log(this.name + ' walks like Student');
//calling a parent method
Student._parent.walk.apply(this, arguments);
}
});
var p = new Person('Jon Doe');
p.walk();
console.log(p instanceof Person) // true
var s = new Student('Joan Doe');
s.walk();
console.log(s instanceof Person) // true
console.log(s instanceof Student) // true
As you can see, this approach fulfills what the OOP requires.
A Child obj can call the methods of the parent class to access overridden methods. (The only difference from CurrentClass._parent and BaseClass.prototype is that the second one requires the consumer of the class to actually know the name of the parent class, which I wanted to avoid).
Creating a constructor had to be simple, in this case... the function itself is the constructor. No need of simple init methods... that are auto called during instantiation.
The cons in the approach I followed:
Does having the extra Nexus dummy function to create the right prototype chain is an issue for memory management?
I haven't had time to make proper tests, and my inheritance chains are not deeper than 3 levels. So the impact there seems to be very tiny.
I could have being using a library for that, but It seemed extremely simple to make it directly and still put some code in the constructors that I fail to see the benefits from having an extra init class for initialization.
What do you think will adding the dummy Nexus function have any noticeable impact?
Upvotes: 0
Views: 114
Reputation: 664548
Does having the extra Nexus dummy function to create the right prototype chain is an issue for memory management?
No. You've just got an (one!) additional object floating around in memory. Move it into the Object._extend
function and it even will automatically garbage-collected.
However, instead of that Nexus
thing you should just use Object.create
. See also Understanding Crockford's Object.create shim.
Upvotes: 2