You are currently browsing the Eric Feminella posts tagged: design patterns

Function Overwriting in JavaScript

Saturday, November 19th, 2011

Whether intentional, or simply a by-product of it’s design, Javascript, being a dynamic language, allows for a level of expressiveness which most any seasoned programmer would come to appreciate. Javascript naturally provides the ability to implement some rather intriguing and quite unique patterns; one of which is the ability to overwrite a function at runtime.

Function Overwriting

Function Overwriting (also known as “Self-Defining Functions” or “Lazy Defining Functions”) provides a pattern which, as stated above, allows for overwriting a function’s definition at runtime. This can be accomplished from outside of the function, but also from within the function’s implementation itself.

For example, on occasion a function may need to perform some initial piece of work, after which, all subsequent invocations would result in unnecessarily re-executing the initialization code. Typically, this issue is addressed by storing initialization flags or refactoring the initialization code to another function. While such a design solves this problem, it does result in unnecessary code which will need to be maintained. In JavaScript, perhaps a different approach is in order: we can simply redefine the function after the initialization work has been completed.

A possible candidate use-case for Function Overwriting is Feature Detection as, detecting for specific feature support in the Browser typically only needs to be tested once, at which point subsequent tests are unnecessary.

Below is a basic example of implementing Function Overwritting in the context of an abstraction of the HTML5 Geolocation API.

Considerations

Since functions are objects in Javascript, it is important to keep in mind that if you add a property or method to a function (either statically or via the function’s prototype), and then overwrite the function, you will have effectively removed those properties or methods as well. Also, if the function is referenced by another variable, or by a method of another object, the initially defined implementation will be preserved and the overwriting process will not occur. As such, be mindful when implementing this pattern. As a general rule of thumb, I typically only implement Function Overwriting when the function being redefined is in a private scope.

Concluding Thoughts

As you can see, Function Overwriting provides a convenient facility for optimizing code execution at runtime. There are many use-cases for dynamically overwriting functions and, where appropriate, they can certainly provide value in terms of performance and code maintainability.

Below you can find an example which demonstrates two basic Function Overwriting implementations. Simply load the page and add some breakpoints in Firebug to test the execution paths; both before and after overwriting each function occurs, or you can simply view the source.
Example