Monday, December 06, 2010

Over the weekend I watched Douglas Crockford’s five part series on Javascript, Crockford on Javascript. Probably one of the best video introductions to a programming language I have ever seen.

The section I enjoyed the most was part 3, Function the Ultimate, especially the section where he discusses object creation. I’ve always disliked prototype based inheritance. It’s clumsy, awkward and lacks encapsulation. Crockford shows a much nicer object creation strategy based on closures, which looks something like this:

Using this technique we can create properly encapsulated objects. In the example above, our animalsApp only exposes a single function, main, new_animal, new_dog and new_cat are all private. The class definitions are very clear, any variables or functions defined in the constructor body are private and we only expose members that we explicitly attach to the object (dog.bark = function(){}).

10 comments:

Whilst this is a nice JavaScript hack to create encapsulated objects, it would have been sooooo much easier for everyone if the powers that be had adopted ECMAScript 4. Then JavaScript would have real classes...

Prototypal object definition doesn't entirely lack encapsulation. It encapsulates data, but doesn't restrict access. However, you can still achieve this with closures while still creating inheritable objects. IMO, this is decorating when you should be inheriting.

Also, this doesn't address the (supposed) access restriction short comings of JavaScript since everything inside of main() still has uncontrolled access to the members of animal/dog/cat. The only thing you've done is blocked the top most level (the context that executes `animalsApp.main();`) from accessing anything in the defined animal objects while still allowing the execution context within `main` to access and alter any property on those objects that it wants. I don't see how this is beneficial as more than an exercise.

j.rebhan: The only method you can override is main() and you can do this only on instances of the object Mike is creating using the standard method of overriding a JS member. object["member name"] = whatever.

Justin: Main can not access the members of dog,cat etc... declared with the var keyword inside of the function. Of course this, like any example code, is trivial. In my script loading library, you can see this a little more clearly. The only method anything outside of my function has access to is the "bootstrap" function. All of the other functions and variables declared inside of it are protected.

Justin: HA my mistake, they can access the members of cat dog, but only because the function is returning them. If the function were to wrap them with an accessor function then they could only access them via that function.