Methods & Properties with Javascript OOP
re-cycledair.com
re-cycledair.com
Pros:
1. You don't have to understand JavaScript to use it
2. You get to have "private" members
3. You don't have to use "this". See point #1.
Cons:
1. Object churn: Every "new" operation creates an object that you proceed to immediately discard
2. Speed: Object creation is slow.
3. Maintenance: Object inheritance is quirky. Lack of "protected" members ends up forcing you to rewrite your "private" members as "public" one, negating pro #2.
4. OOP: The "instanceof" operator won't work on your instanciated objects. You'll need to define your own introspection mechanism to tell which instance comes from which class.
My take:
- It has a lot in common with the module pattern, commonly used to namespace things.
- It's okay to use it, or something like it, for objects that get relatively few instances.
- If you're going to ignore "this" in your constructor, don't use the "new" operator to create your objects.
- Don't use this pattern for something that gets instantiated a lot.
- Think carefully before using this pattern if you intend to use any kind of class inheritance with it.
self: var a = []; function b(){ var c = {}; c.d = function(){}; return c }; for (var e = 0, f = 100000; e < f; e++) a.push(new b)
prototype: var a = []; function b(){ return this }; b.prototype.c = function(){}; for (var d = 0, e = 100000; d < e; d++) a.push(new b)
There's no syntactic support for class-based inheritance, so it's a bit verbose, but not really complicated:
function AClass(foo) {
this.foo = foo;
}
// methods are shared between instances
AClass.prototype.alertFoo = function() {
alert(this.foo);
};
function ASubClass(foo, bar) {
// call parent constructor
AClass.call(this, foo);
this.bar = bar;
}
// simulate inheritance via method aggregation
for(var name in AClass.prototype) {
if(AClass.prototype.hasOwnProperty(name))
ASubClass.prototype[name] = AClass.prototype[name];
}
// alternatively, use proper inheritance
ASubClass.prototype = Object.create(AClass.prototype);
ASubClass.prototype.alertFooBar = function() {
alert(this.foo + ' ' + this.bar);
};
This is what I'd call the idiomatic way to implement classes in Javascript.Instead of adding methods to the prototype, you can also add them to the instance within the constructor. This way, you can simulate private members as such methods close over the constructor's lexical scope -- but this comes with a performance penalty.
Most custom class implementations just provide sugar over these patterns.
The following example illustrate how one may have private and public members as well as private and public methods and how to access them.
function AClass(foo)
{
this.foo = foo; // public member variable
var bar = "bar"; // private member variable
function fun1() // private method
{
bar = this.foo; // private and public var access
}
this.fun2 = function () // public privileged method
{
bar = this.foo; // private and public var access
}
}
A public method defined with prototype doesn't allow to access private member variables. This is the difference between privileged methods and public methods. The privileged method can access private methods because of closure.This is all very different from other OOP languages. I just add these for clarification. It may be helpful to some readers.
By convention one may also add an underscore in front of private members and function identifiers to make the difference clearly visible in the code.
Would Object.create also inherit private functions and members ?
No, it would not - these so-called private members and methods have nothing to do with inheritance, but rather lexical closure.
However, as the super constructor is called, priviledged methods will be present and still have access to the private variables.
See also http://stackoverflow.com/a/1441692/48015 for a more comprehensive overview over different access levels.
The missing infos in the StackOverflow answer are how do one instantiate such class and access it's methods and public and shared members ? var obj = new MyObj() ? obj.publicSharedVar ?
MDN: https://developer.mozilla.org/en/JavaScript/Reference/Functi...
short stack overflow: http://stackoverflow.com/questions/500431/javascript-variabl...