Issue

01

A DIFFERENT TYPE OF AGENCY

As a collective, The Factory Interactive is fueled by a passion for developing enduring messages conceived through a marriage of design and technology. At the core, we are explorers of possibility and architects of memory. We create rich immersive experiences that increase message retention and reward the audience. Our mission: give personality to products, resulting in a stronger, more effective brand.

Contact Us
305.752.9400
info@thefactoryi.com

The Factory Interactive’s eZine into the world of Online Marketing & Design Interaction.

Cleaner Javascript Design By Briam Rodriguez

Cleaner Javascript Design By Leveraging Closures and the “Function as Object” design pattern

Intro
Javascript is a flexible, object oriented, language which is usually dismissed as a toy language for being too simplistic, or for lacking sufficient features with which to develop applications. Part of this dismissive attitude stems from a misunderstanding of Javascript’s greatest strength, its flexibility.

It’s so flexible in fact, that it leads to spaghetti code more often than not because the developer approaches javascript development without a solid design pattern in mind. Most javascript scripts that I’ve seen (and some of my own, I must admit) have turned out to be horrible tangled messes of asynchronous callbacks (functions which are scheduled to be run at an unspecified future time) to which even more cruft is added as application requirements are added or removed. Essentially, most of these “one-off” scripts contain the same trademark flaw: they fail to model their entities appropriately, leading to inconsistencies all across the board.

There are three solutions to these recurring problems, namely the judicious use of closures, the “Function as Object” design pattern, and the proper modeling of program entities.

Functions As Objects
Many languages have special constructs to define an object, viz. keywords relegated to that specific use. Javascript has no such constructs, though it has the capability to define objects, and it approaches the task in an odd but satisfactory manner.
It turns out that functions (as in most of the better languages) are actually first-class objects themselves. This means that they can be assigned, transferred, have properties added to them dynamically, can (usually) be created anonymously, and can reference themselves (amongst other interesting properties).

We take advantage of the fact that javascript can define anonymous functions inline and use it towards our “Function as Object” pattern through the use of the “new” keyword. The “new” keyword takes the object given after it and creates a reference to a new, separate copy of the defined object.

Let us examine this example (a record for a person), assuming it is in the global scope:

    // define a new person object

    var Person = new function() {
    };

This would create a new object “Person” in the global application namespace, with no properties or methods. Right now this is of no practical use, because the object contains no data (properties), and no operations (methods) can be performed upon it. Before we can assign it properties though, the Person object needs to have a reference to itself.

Speaking of properties, how can we assign any if we do not know where they are to be assigned?

We could use the global name “Person” to assign the object attributes, but what happens if we change the object’s name to “HumanBeing”? That would be out of the question since our references would break, and each would need to be individually changed.
We could use the the “this” keyword which references the current call-chain, but that would break if one of our methods is used as a callback. (This is due to the fact that the meaning of the “this” keyword depends on how a function was called.) Or, we could use something called a closure; and pass a reference around subtly and make our lives easier.

I will opt for the latter.

Closures
You may have heard of the term closure before; but what is it and why is it so useful? A closure is simply a function which encapsulates a reference to its containing environment. Absolutely everything… container, properties, methods. the whole kit is passed along. This in itself is not an exciting thing, but when used carefully it can do some pretty amazing things like assist in generating customized functions, or in our case, encapsulate a reference to our parent object. Let’s see how we can use a closure to provide a consistent access point into our object, independent of caller.

Take a look at the our Person object:

    var Person = new function() {
        var self = this;

        self.first_name = "John";
        self.last_name = "Doe";
        self.birth_date = "10/24/1900";

        // notice the use of anonymous "lambda" functions to assign methods to the object

        self.get_full_name = function() {
            return(self.first_name + " " + self.last_name);
            };
        };

What do you see? When we execute the code we get:

    js> Person.get_full_name()
    John Doe


Properly Modelling Your Entities

Using this design pattern we can model our entities and save time and effort, all while beating more complex languages to the punch!

What we have done is taken the current value of the “this” keyword, and caused a global reference to be passed into all of Person’s methods. This might seem similar to you if you’ve ever programmed Python, for example, where the self keyword is part of all objects and used in exactly the same way. This particular design pattern, of “Function as Object” + closures is something which makes programming in javascript hassle free and makes things work as expected. You can even call Person’s methods in javascript callbacks (from jQuery for example) and as long as you reference self, you will not have any issues as to when the “this” keyword really is “this” or “that” or something totally different altogether!

Consider this example code:

    // Notice how I omit the "new" keyword before the function declaration
    // in order to create a class definition instead of a class instance.
    // The "new" keyword is usually used to create instances of a class
    // defined in this way.

    var PersonClass = function(first_name, last_name, date_of_birth) {
        var self = this;

        self.first_name = first_name;
        self.last_name = last_name;
        self.date_of_birth = date_of_birth;

        self.get_full_name = function() {
            return(self.first_name + " " + self.last_name);
            };
        };

    var John = new PersonClass("John", "Doe", "10/24/1900");
    var Jenny = new PersonClass("Jenny", "Doe", "10/24/1900");

    js> John.get_full_name()
    John Doe

    js> Jenny.get_full_name()
    Jenny Doe

It doesn’t matter whether get_full_name is invoked directly or indirectly via callback because the reference to the internal object is passed in via a closure. Now that is object orientation that could rival even the best of OOP languages!

Conclusion
Use of the “Function as Object” design pattern, coupled with usage of the self reference/closure idiom is a powerful tool to make javascript look and feel like the big boys of programming, whilst keeping the simple flexible design of the javascript language available at your fingertips. It removes the inconsistencies encountered when calling methods or accessing parameters via call-back, isolates the way you access data from the way that methods are called (function call chain), encapsulates your data, and is just plain overall fun!

Post to Twitter


Filed under: Uncategorized — @ 2:00 pm

Comments (0)

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment



Subscribe to our feed

subscribe

Search

Learn More

Effective SEO marketing requires meticulous analysis of keywords, link relationships, information architecture and the site's visual design.
Is your web solution working for your business? Contact a digital marketing expert at The Factory Interactive to find the answer.