Creating a JavaScript Library

I recently wrote a JavaScript library for creating random colors and color schemes, and while I found a number of helpful resources that guided me through the mechanics of HSV color-space manipulation, there was a surprising dearth of information on JS library best practices. Since my background in JS up until recently was fairly simple scripting, this added some friction to the creation process for me.

The goal of this post is to ease others into the writing and maintenance of their own libraries by demonstrating via a simple example the proper way to instantiate and define a library in JS.

Before we go any further, here are two assumptions I’m making:

  • You are familiar with the capabilities of JavaScript and other C-like language.
  • You don’t plan to create a JQuery plugin. Generally, a JavaScript library has no dependancies. If you think you need JQuery to do your work, you might not.

The first hurdle I encountered was how to properly think of a JavaScript library. In C/C++ a library is a collection of functionality and generally doesn’t require a great deal of structure. JavaScript works a bit differently, and so some research was required. My final conclusion is that a Javascript library is an independent module wrapped in an object that does not pollute the global namespace by defining functionality outside it’s own scope.

Based on this, let’s naively define a Library:

var Library = {
    name: "Timmy",
    greet: function(){
        alert("Hello from the " + Library.name + " library.");
    }
}

This library is what is known as an object literal. To invoke the greet function, we would write:

Library.greet();

As greet is a member of the Library object. Now, what if we wanted the name variable to only be available to the Library itself? This method provides no way for us to accomplish this. Unfortunately, not only is our Library’s name available to us via Library.name, but the Library itself must access it’s own data by invoking itself. This is messy and sub-optimal.

The answer to this is to define the library as a function which creates an object for us to access. This allows us to create and use private variables and functions. Here is what that would look like:

function Library(){
    var name = "Timmy";
    this.greet = function(){
        alert("Hello from the " + name + " library.");
    }
}

In this implementation, Library.name will not be exposed globally, but internally the library may still access the name variable. The greet function continues to be public because it is defined as a member of Library via the this keyword. Stewardship over what is exposed to whom is simply good design practice.

However, now we’ve run into another problem. Imagine a scenario where someone has included your awesome library in their website but already has a variable named Library.

var Library = {
    num_books: 4536,
    genres :[
        "sci-fi",
        "fantasy",
        "fiction",
        "dry coding books"
    ],
    average_net_income: -4130.43
}

//Some arbitrarily large amount of code

Library.greet();

Now your definition is being overwritten and the user is getting a ReferenceError. The answer is to wrap your library in a function which defines it, and then invoke this function conditionally if your global namespace is clear of conflicts. A dissection of this technique will follow, but here is the final result:

(function(window){
    //I recommend this
    'use strict';
    function define_library(){
        var Library = {};
        var name = "Timmy";
        Library.greet = function(){
            alert("Hello from the " + name + " library.");
        }
        return Library;
    }
    //define globally if it doesn't already exist
    if(typeof(Library) === 'undefined'){
        window.Library = define_Library();
    }
    else{
        console.log("Library already defined.");
    }
})(window);

So a few new things have reared their heads here. The first is the closure which wraps the entire definition:

(function(window){
    //CODE
})(window);

The way this works is that it creates its own encapsulation of the contained code, and therefore its own namespace. It also executes automatically, via that syntactic sugar at the end “(window);”. Here is a very simple example:

function some_function(){
    console.log("k");
}
some_function();
//is equivalent to
(function(){
    console.log("k");
})();

Next, we have ‘use strict’, which is an optional setting, but not unlike the way we are defining our library is simply good practice. A happy coincidence is that due to the way we have enclosed our definition, strict mode will apply to our entire library with just one invocation. Bonus Points!

Following this, we come to the definition function itself:

function define_library(){
    var Library = {};
    var name = "Timmy";
    Library.greet = function(){
        alert("Hello from the " + name + " library.");
    }
    return Library;
}

The definition function actually uses our first technique to create an object literal and then tacks functionality and data onto it at a later point. This also maintains our ability to have private and public interfaces. Note that at the end of the definition, the function returns the Library object you’ve been building upon.

Finally, we come to the conditional which ties this all together:

if(typeof(Library) === 'undefined'){
    window.Library = define_Library();
}

This checks to see if Library is already defined elsewhere, and if not runs your definition function to create it.

I hope this helps in some small way. The easier it is to take an idea from conception to completion, the better the world becomes.

Creating a JavaScript Library

I recently wrote a JavaScript library for creating random colors and color schemes, and while I foun…

s3Slider jQuery Plugin & Tutorial

The s3Slider jQuery plugin is made by example of jd`s smooth slide show script. Usage: HTML: Sample …

jQuery Optimization: Avoid Unnecessary Selector

Common subexpression elimination is a common way to optimize any programming code. Doing unnecessary…

Fading Links Using jQuery: dwFadingLinks

Earlier this month, we posted a MooTools script that faded links to and from a color during the mous…

jQuery Flash Plugin

This jQuery plugin is for embedding Flash movies. Pages are progressively enhanced when Flash and Ja…

jQuery Optimization: Optimize Selector

We can also optimize our selector other than being a bit specific on our selector. The key to optimi…

jQuery drop down menu: droppy

Quick and dirty nested drop-down menu in the jQuery style. I needed a nav like this for a recent pro…