Single var

Declares and initializes all function variables with a single var.

The jQuery authors follow the Single var Pattern religiously. There are no exceptions.



Overview


The first line within the module's function body is single var followed by about 2 dozen variable declarations and initializations. This is the Single var Pattern.

(function (window, undefined) {
var
    rootjQuery,
    readyList,

    document = window.document,
    location = window.location,
    navigator = window.navigator,

    _jQuery = window.jQuery,
    _$ = window.$,

    core_push = Array.prototype.push,
    core_slice = Array.prototype.slice,
    core_indexOf = Array.prototype.indexOf,
    core_toString = Object.prototype.toString,
    core_hasOwn = Object.prototype.hasOwnProperty,
    core_trim = String.prototype.trim,

    // more ...

})( window );

As you know variables get hoisted to the top, which can lead to unexpected results. The Single var pattern states that all variables in a function should be declared, and possibly initialized, by a single var at the beginning of the function body. The jQuery authors strictly adhere to this rule with only one var in each function.

Unfortunately, strictly enforcing the Single var pattern can sometimes lead to code that seems contrived and unnatural; take a look at jQuery's grep method:

grep: function( elems, callback, inv ) {
    var retVal,
        ret = [],
        i = 0,
        length = elems.length;

        inv = !!inv;
        // Go through the array, only saving the items
        // that pass the validator function
        for ( ; i < length; i++ ) {
            retVal = !!callback( elems[ i ], i );
            if ( inv !== retVal ) {
                 ret.push( elems[ i ] );
            }
        }

        return ret;
}

Here we have a single var with four variables, three of which are initialized. In the middle of this function is a for loop that seems incomplete because the variables i and length are already defined and initialized at the top. You see these kinds of for loops throughout the library.

We prefer to have the looping variables declared and initialized where they are used (right in your face, so to speak) without having to guess whether i or length exist and/or have been initialized. Doing it this way would change the code to this:

grep: function( elems, callback, inv ) {
    var retVal,
        ret = []; 

        inv = !!inv;
        // Go through the array, only saving the items
        // that pass the validator function
        for (var i = 0, length = elems.length; i < length; i++ ) {
            retVal = !!callback( elems[ i ], i );
            if ( inv !== retVal ) {
                 ret.push( elems[ i ] );
            }
        }

        return ret;
}

We think this code makes its intentions more clear (i.e. more in your face).



  Module