This post was published on Saturday 21st of July 2007.
It is already six years ago, that Douglas Crockford wrote what I believe to be the first article about private members and methods in JavaScript. I've only first read it last year and it struck me as being an under-used technique in JavaScript. Well, under-used by me, at least. Last week I was experimenting a little bit more with it and I found that techique can also be used to create private constructors.
For those who don't want to read the original article, here's a quick recap. Doug writes there are three types of properties and methods in JavaScript:
// Public constructor and properties
function Constructor(...) {
this.property = value;
}
// Private methods and properties
function Constructor(...) {
var property = value;
function method(...) {...}
}
// Privileged methods
function Constructor(...) {
this.method = function (...) {...};
}
Last week I was reminded of this article when I was chatting with one of my colleagues about OO programming in JavaScript. I told her that OO in JavaScript was nothing more than defining a regular function with some this stuff in there and calling that function with the new keyword. More exactly:
// Regular function with some "this"
function SomeObject( ) {
this.property = "Hello, world";
this.method = function( ) {
return this.property;
}
}
// Call the function with the "new" keyword:
var so = new SomeObject();
// Presto! We've got an object with a property and method:
alert(so.method()); // "Hello, world"
What's especially noticable, is that even though the function/constructor has no return statement, calling it with new automatically returns it as an object. Well, I think it's noticable.
So, this got me thinking: if you can have private methods by defining a regular function inside a constructor, will that method become a private constructor if you call it with the new keyword? The answer, of course, is yes:
function PublicConstructor() {
function PrivateConstructor() {
this.property = "Hello, world";
}
this.property = new PrivateConstructor();
}
var pc = new PublicConstructor();
alert(pc.property.property); // "Hello, world"
After I confirmed that it works I asked myself: "what is it useful for?" Unfortunately, I couldn't really come up with something compelling. One example I did come up with was a situation where you want to create objects that only make sense in a certain context, like nodes in a tree. Using this technique you could implement it so the node can only be constructed by the tree itself:
function Tree() {
function Node() { ... }
this.nodes = new Array();
this.addNode() {
this.nodes.push(new Node());
}
}
An added advantage is that because the function name Node is local, it could also be used globally or inside other constructors without causing conflicts. For example, you might also want to implement a graph object with nodes. These graph nodes are of a completely different type than tree nodes but this method would allow for identical constructor names:
function Graph() {
function Node() { ... }
this.nodes = new Array();
this.addNode() {
this.nodes.push(new Node());
}
}
Still not very compelling, but an interesting technique nonetheless.
Have something to say about this post? Share your thoughts!
This post was published on Saturday 21st of July 2007.
The previous entry was "Dutch Guild for Front-End programmers".
The next entry is "Turning arguments into an array".