An JavaScript Clinic for premature Initalization

Developers Kindergarten

6 years later and this advice still resonates, with the right message too. If your “thing” is what we call today “low-level Java Script”, perhaps you might read carefully.

[2014 APR 13]

Premature Initialization is the source of all evil. Yes? OK? Fine then. That is a bombastic blog statement out of the way. Now let’s dive into some serious JS.

First let me be clear: There is hardly anything new in this post. This subject has been presented before.  Still, I see too much of a JavaScript code, these days, where this simple programming idiom, is somehow still not in use. So why not revisit this issue for the sake of new generations.? OK, then let’s start.

We will not start with initialization but with modularization. One JavaScript idiom in widespread use. Yes, I am sure anyone will agree that JavaScript closures are in widespread use these days.

System Initialization
Left is before the start, right is the same system Initialized. But how?

Here is a trivial one:

I hope we do not have to debate here why do we use JS closures to implement kind-of-a-modules, etc. The above is by far the most prevailing pattern for the creation of a kind-of-a-module using JS. It is based on the definition and immediate calling of the anonymous function. Right?

Well … not exactly “right”. Here is the problem. A lot of very happy JS developers are using this pattern for implementing initialize-once-use-later “clever” mechanism:

Above we have an immediate initialization of the Rx. That is because closure is just an anonymous function that is immediately called (executed). So inside the closure, we prepare all the static or constant content we will need for the actual worker function to use when subsequently called. And because all of this initialized and hidden “closure” stuff stays hidden, you have this warm feeling about being clever JavaScript uber-geeks, which is always a “good thing”, is it not?

Very quickly this becomes your habit and you happily sprinkle this “awesomeness” all-around your “awesome” code. But herein lies your problem, as there are problems with this pattern, overzealous usage.

First of all this pattern if used “all-around a place, by everyone” (meaning by “tons” of libraries included)  slows down the loading time of pages where your “awesome” code is loaded too. This is simply because immediately after the code gets loaded, there is a lot of JS work happening, which is executed all-around your little or large closures. before any event has a chance to be dispatched for example. Therefore (and simply) page loading time can be vastly expanded, in presence of a lot of complex initialization code inside a lot of closures. And remember, not just in your code but in numerous jQuery plugins and such, that you are including in your “awesome”, single page, web app.

Second (big) issue. This mechanism can not be used to reference other parts of the object which it is part of. Quick explanation:

The above might be a good example of programming resilient to change. But JavaScript will not do it and instead, it will “explain” to you, what is wrong:

Above is because you are immediately executing a closure which is how you thought you will code your ToolBox.is4d() function. So from the closure, you are calling ToolBox.rx. Which is “no-can-do” because ToolBox at that moment in time is not fully made yet. It is simply null.

Third problem. The closure mechanism presents difficulties when referencing the variables or objects external to the closure.

The above code is not “adorned” with error checking, because of usage of assert() on the required type. Clever stuff? Robust coding?

I beg to differ. This code also depends on an external library and thus references some external string storage in order to prepare the message for the eventuality it might be needed inside the worker. And yes, in turn, this string storage, once was, but then it might or might not be defined when needed for a variety of reasons. It is likely defined in another module not made by you. Or even bought by your company. That js file might be simply not included before this code, by mistake. Or someone somewhere, has decided after some time to quietly insert a “modernised” new version? So perhaps MSGID constants are not used any more, etc. If any of these is true, your code will stop at the javascript file loading initialization time. Which is the worst time to stop and notoriously difficult to debug. The point I am making here is not that your code is lousy, the point is that it is lousy and it also happens before somebody else can spot it in a normal way. Teamwork, remember?

Your good company has decided to send you to me. To the “Clinic for premature Initialization”. Welcome. Relax.

There is a medicine for you. It is effective and it works. Stop shaking, calm down and think. The Source of the evil was that you did initialization prematurely. Yes, yes. As everyone else does and they are not punished (yet). But that is not the point.

The initialization mechanism you have used is not lazy initialization. It simply happens too soon! It is even not an initialization pattern! So … Just say no to closure as an initialization pattern. Do not confuse initialization and modularization. Enough of this long patronizing and let us give you the solution and medicine:

Phew! That is a lot of comments for such a little function. Ultimately this implementation pattern depends on the ability of JavaScript to redefined the function inside its own body. I can not overstate how important this pattern is. It could (and should) be used everywhere in your code where immediate initialization happens. If it has not hurt you yesterday, it will tomorrow. So remove it today. Back to the code. This also is a solution to a second problem we presented.

Closures and Lazy Init Pattern combined

But. “There is no silver bullet” as it is already known. This pattern if used everywhere can lead to a lot of variables and object which GC might (or will) not be able to swipe, thus potentially our lazy initialized uber-clever-code might keep a lot of memory in use.

Here one can use an excellent combination of lazy initialization and standard closures. Here is the problem again. Watch closely.

Above, it is very likely that GC will not know1 that a,b,c,d,e can be swiped. One simply can not be sure. Instead of wondering will it or will it not, just use a standard closure. The key is to encapsulate the closure inside the lazy initialization!

Voila! All of your to-be-temporaries are now temporaries indeed. When the anonymous closure function exits they are all swiped; just the result is preserved.

Conclusion

Examples here are deliberately simple. In order to explain the Lazy Init aka just-in-time mechanism.
It is important to understand the implications when using the “self-igniting” mechanism of the anonymous function closures-as-modules. Use both patterns but know when to use which one. And above all: Do not confuse the two.


1: Although these days modern JS engines do contain some pretty clever GC’s.

3 thoughts on “An JavaScript Clinic for premature Initalization”

Comments are closed.