It would nice if there was an article to summarize all the ways of emulating a class in Javascript. Over the years I've seen a dozen different ways and I never know what's the pros and cons of them, or at least the principals behind them. All these different ways don't help me when I'm looking at someone else's code. There are just way too many ways to do it.
While in principle, Javascript's object system is prototypal, in practice you can use it as if it were class-based; in fact, before the addition of Object.create() with ES5, you only could get proper prototypal inheritance through non-standard extensions like __proto__ or a hack using temporary constructors.
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.
In your example cygx, this.foo is a public member variable.
As you say, it is possible to have private member variables but this implies some constrains.
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 ?
Thank you very much. It's the first time I see this pattern and a clear specification. I used privileged methods everywhere instead of shared public methods based on this article: http://javascript.crockford.com/private.html
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 ?
That's because there is no OOP in javascript as in other languages like java or python, javascript only implements natively prototypal inheritance and lexical scope. This very important concept is always misunderstood because of the syntactic sugar like 'new' and 'this'.