10 things you need to know about JavaScript

Back in 1995 Netscape wanted a language with a simple programming model, but flexible enough for building real scalable applications. Curious, that Brendan Eich accomplished the task in a few weeks. So, we have JavaScript which seems so simple that many people don't even bother to learn the language while using it. And yet it works! However, it turned out to be one of the reasons why JavaScript was dramatically misunderstood . Yes, it looks like a language of the C-family and, when starting with JavaScript, programers are just writing in C, Java, PHP or other language style. But JavaScript is no subset of any of these languages. You may find JavaScript even a superior language, but you have to know how to do things in JavaScript way. Let's take for instance OOP. Majority of programmers is familiar with the OOP of the classical school. So, switching to JavaScript the people get confused by absence of classes, interfaces and such. In fact, it doesn't mean JavaScript isn't object-oriented, quite the contrary. However, prototype-based OOP differs and to use it, one has to know how. Any requirement (scopes, namespaces, member visibility, object inheritance and so on) can be achieved with but a trick. You cannot learn those from the documentation. There is no centralized documentation for JavaScript, but EcmaScript specs (JavaScript is an implementation of ECMA-262 standard) and tons of references (e.g. MDN JavaScript References). References and, even more so, the specs are not meant to cover programming patterns, but the language itself. Of course, there is plenty of books and you may find some (e.g. "Secrets of the JavaScript Ninja" by John Resig, "Learning JavaScript Design Patterns" by Addy Osmani ) pretty useful. Besides, you can learn straight from the code, since we are lucky to have tons of substantial JavaScript applications available in open-source (jquery.com, yuilibrary.com/projects/yui3/, backbonejs.org, modernizr.com, raphaeljs.com and so on). In either case you may stumble over programming techniques unknown to you. I've collected here some commonly used practices which may help you.


Programming Style

It's much easier to read the code if you are familiar with the its coding style. The good news is that most of the open-source code adheres one of only a few coding style guides or, at least, a style derived from those. Most widely used Idiomatic.js, jQuery Core Style Guide, Dojo Style Guide and Douglas Crockford's Code Conventions. Actually, all of them are very similar to each other. Here some common substantial statements:

  • The var statements should be the first statements in the function body.
  • Method and variable names in camelCase
  • Constructor function in PascalCase
  • Symbolic constant names in uppercase

(function() {
var CONSTANT_EXAMPLE,
      variableExample,
      ConstructorExample = function() {
             return {
                   methodExample: function() {
                   }
             } 
      } 
}());
  • Always prefer `===` over `==` (unless the case requires loose type evaluation)
  • Declare static objects as {} and array as []

There are some tricks which so commonly used that nobody cares to mention in style guides. You are just expected to know and use such. E.g.

variable = argumentVar || "Default value";

If argumentVar is defined and truthy (e.g. not empty), variable receives argumentVar. Otherwise, "Default value".

condition && foo();

Only when condition (can be expression) is truthy, foo function is called.

Reading code you can run into following recursion pattern:

(function( arg ){
    console.log( arg );
    if ( arg-- > 0 ) {
        arguments.callee( arg );
    }
})( 10 );

Don't adapt this practice. callee is referred as unsafe action in ECMAScript 5's strict mode and will cause an exception.

It also makes sense to mention here some commonly used techniques for type conversion:

// to a boolean
console.log( !!5 ); // true
// to a string
console.log( 5 + "" ); // "5"
// to a number
console.log( parseInt( "011", 10 ) ); // 11
console.log( +5 ); // "5"
// it also works through bitwise operators
console.log( ~~"5" ); // 5
console.log( "5" >> 0 ); // 5
console.log( "5" >>> 0 ); // 5
// a nodeList/arguments to array
console.log( [].slice.call( document.querySelectorAll( 'a' ), 0 ) );

Declaration of a multiline text variable is often done by single-line strings concatenation. It isn't very useful in practice though. You may encounter a long string spitted by back-slashes:

var variable =  "string\
string\
string";

I would rather not recommended this approach. Just a trailing space will cause syntax error. In JavaScript 1.6 / E4X (Nov. 2005) was introduced a statement which is very like heredoc:

var variable =  <>
string
string
string
</>.toString();

Scopes

You probably know that JavaScript does not have block scope. So, in order to define a scope for a module (a script block) and isolate it from the global scope we use self-calling anonymous (labda) function. Apparently, we can consider it as a generally accepted practice.


(function(window, undefined) {
    var document = window.document;
    // Module body
}(window));

Some questions may arise concerning what extra arguments we pass into. I would recommend passing window through to be addressed as a local variable rather than as global. That slightly speeds up the resolution process and can be more efficiently minified. As for undefined, this way we ensure that undefined isn't defined by chance. Yeah, JavaScript sometimes drastically inconsistent: NaN (not a number) is a number, undefined being an object can be overridden and get defined. That was fixed in EcmaScript 5 (JavaScript 1.8.5) and not an issue in new browsers. Yet, we have to take care for legacy browsers.

See also Scope in JavaScript


Objects

In classical JavaScript inheritable objects are declared either so:

var Constructor = function(){
     this.prop = 'Value'; 
}

or so:

var Constructor = function(){};
Constructor.prototype.prop = "Value";

In any case you can make an instance of the object and reach its public members like that:

var o = new Constructor();
console.log( o instanceof Constructor ); // true
console.log( o.prop ); // Value

or using EcmaScript 5 notation:

var o = Object.create( Constructor.prototype );
console.log( o instanceof Constructor ); // true
console.log( o.prop ); // Value

Any expression preceded by var statement won't be accessible outside the constructor function scope and can be considered as a private member:

var Constructor = function(){
    var privateProp = "Value",
        privateMethod = function() { 
            return privateProp;
        };
    this.publicMethod = function() {
        return privateMethod();
    }
},
o = new Constructor();
console.log( o instanceof Constructor ); // true
console.log( o.publicMethod() ); // Value

See more Private Members in JavaScript by Douglas Crockford


Cloning

Cloning in computing means creation of an object copy where the copy gets the state of the initial object. So, the data kept in public properties of the object get copied as well. You likely know that if we assign an object to a variable, we'll get no new object, but a reference to the initial one.

What the difference between cloning and instantiating? The second one creates a new object of empty state while the first provides a copy.

Why do we need cloning? Cloning is used in various application design solutions. For example, Prototype design pattern by GoF shows how to reduce the number of classes when they differ only by the states. It's based on cloning.


var originalObj = { prop: "value" }, 
    clone = Object.create( originalObj );

Prototypal OOP and pseudo-classical inheritance

In classical OOP we are used to deal with objects which are instances of the class defining their structure and behavior. Contrariwise, in prototype-based languages we have no predefined classes, but only objects, which, however, may serve as prototypes for new objects.

Every derived object has a link to its prototype. So, when a method or property requested from object, the system walks through the delegation chain until it finds it on one of formative prototypes. Besides, any object assigned to a property of another one, makes no copy but reference. That give us a dynamic model, where change in one of related object immediately reflects on another one. This model supports both generalization (is-a) and aggregation (has-a) relation types.

Nevertheless, the JavaScript community didn't accepted prototypal OOP very well. It's widely used now in open-source code various solution emulating classical OOP. The common way to achieve pseudo-classical inheritance (pseudo-classes extending each other) is instantiating from supertype into substype's prototype:


var o, 
    SuperTypeConstructor = function(){}, 
    SubTypeConstructor = function(){};
    
SuperTypeConstructor.prototype = {
    a : "supertype's a",
    b : "supertype's b"
};
SubTypeConstructor.prototype = new SuperTypeConstructor();
SubTypeConstructor.prototype.a = "subtype's a";

o = new SubTypeConstructor();

console.log( o instanceof SubTypeConstructor ); // true
console.log( o instanceof SuperTypeConstructor ); // true
console.log( o.a ); // subtype's a
console.log( o.b ); // supertype's b
console.log( o.__proto__.a ); // subtype's a
console.log( o.__proto__.__proto__.a ); // supertype's a

Here is shown an example of walk through the object prototype chain. Actually, __proto__ property isn't standard. You rather not rely on it. There is no way to achieve deep inheritance hierarchy in ECMA-262 until now. But it may change in the 6 edition, though. You can see it from the example taken from EcmaScript Harmony proposals:

class ConcreteClass extends BaseClass {
  constructor(x,y) {
    super();
  }
}

Module patten

The pattern known as module is widely spread nowadays, largely due to enthusiastic evangelism of Addy Osmani.

var Module = (function() {
    var privateMember = "secret";
    return {
      publicMember: function() {
        return privateMember;
      }
    };
  })();

I do love this pattern for it makes your objects clean and readable. What I miss is pseudo-classical inheritance. So, I wrote a small factory JSA which solves it:

(function( jsa, window, undefined ) {
"use strict";
var AbstractModule = function () {
        return {
            inheritedProp : "inherited property",
            publicProp : "original property"
        };
    },
    ConcreteModule = function () {
        var _privateVar = "private";
        return {
            __extends__: AbstractModule,  // ConcreteModule extends AbstractModule
            getPrivate : function () {
                return _privateVar;
            },
            publicProp : "overriden property"
        };
    },
    // Make an instance of ConcreteModule
    o = ConcreteModule.createInstance();
    console.log( o instanceof ConcreteModule ); // true
    console.log( o instanceof AbstractModule ); // true
})( jsa, window );

Magic methods

Are you familiar with magical methods of PHP? It gives you control over property access and mutation, method invocation and such. The language gets much more flexible and you can apply new fancy patterns.

Here below is an example of property overloading:

var obj = {  
      a: null,  
      get member() { return this.a; },  
      set member( x ) { this.a = x; }  
};

You also can run into the following form, introduced in EcmaScript 5 (JavaScript 1.8.5, Jul 2010):

var obj = {};
Object.defineProperty( obj, "member", {
   get : function(){ 
        console.log( "Member accessor invoked" );
        return bValue; 
   },  
   set : function( newValue ){ 
        console.log( "Member mutator invoked" );   
        bValue = newValue; 
   },  
   enumerable : true,  
   configurable : true}
);  

obj.member = "value";
console.log( obj.member );

Method overloading for now is only available in Firefox and is recognized as non-standard. Pity, I do love their multiple inheritance simulation.

var obj = {
    __noSuchMethod__ : function( arg ){ 
        console.log( 'Unable to call "' + arg + '" function' );
    }
}
obj.undefinedMethod(); // Unable to call "undefinedMethod" function

To close the subject, here how you can define the primitive value of the object:

var obj1 = {
  valueOf: function () {
    return 1;
  }
}, obj2 = {
    valueOf: function () {
    return 2;
  }
};

console.log( obj1 + obj2 ); // 3

Cascade

If you are familiar with jQuery, you probably noted multiple statements like

$( "#exampleNode" )
	.addClass( "highlighted" )
    .css( "visibility", "visible" )
    .html( "Lorem ipsum" );

The technique is called method chaining (cascade) and make code cleaner. But how can it be achieved? Pretty easy. We just have to make every of chainable methods to return the object (the current object itself):

var $ = function( query ) {
    var $ = function( query ) {
    	var node = document.querySelector( query );
    	return {
    		addClass: function( className ) {
    			node.className = className;			
    			return this;
    		},
    		css: function ( prop, value ) {
    			node.style = prop + ":" + value;
    			return this;
    		},
    		html: function( html ) {
    			node.innerHTML = html;
    			return this;
    		}
    	}
	}
	return new $( query );
}

Exceptions Handling

Try/catch technique is especially efficient when it's conditional:

function Constructor1(){
}
function Constructor2(){
}

try {
    throw new Constructor1();
} catch ( err if err instanceof Constructor1 ) {
    console.log( 'Constructor1 thrown exception' )
} catch ( err if err instanceof Constructor2 ) {
    console.log( 'Constructor2 thrown exception' )
} catch(e) {
    throw(e);
}

Besides, JavaScript provides predefined Error object and its instances EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError. You can inherit them in your own exception type:

var CustomException = function( message ) {  
        this.name = "CustomException";  
        this.message = message || "CustomException thrown";  
    }  
    CustomException.prototype = new ReferenceError();  
    CustomException.prototype.constructor = CustomException;  

    try {  
        throw new CustomException( "custom message" );  
    } catch (e) {  
        console.log( e.name );     // "CustomException"  
        console.log( e.message );  // "custom message"  
        console.log( e instanceof CustomException ); // true
        console.log( e instanceof ReferenceError ); // true
        console.log( e instanceof Error ); // true        
    }

Overriding global objects

JavaScript is freakishly dynamic. You can override any object or its member run-time (except if it is intentionally sealed). It can be even objects of global scope and first-class objects, what gives you enormous power over the language.

For example you can rewrite that clumsy alert function by your own one showing the message on a fancy-styled overlay:

window.alert = function( message ) {
    console.log( "Display " + message + " in some fancy way " );
}

alert( "my message" ); // Display my message in some fancy way

But you rather don't override global objects unless you really have to.

Do you know about aspect-oriented programming paradigm? What's relevant here that in AOP you can enable cross-cutting concerns such as logger on any parts of application whenever you wish. It turned out that JavaScript provides you with such trick. You can hook into any existing code, e.g. third-party made one, not changing it.


var jQueryBakup = window.jQuery
window.jQuery = function( selector, context ) {
    console.log( "jQuery is called with arguments: ", selector, context );
    return jQueryBakup( selector, context );
}

console.log(jQuery(window));

Non-blocking JavaScript

You probably know that if you keep script tags referring to external sources in page head section it may slow down page generation. So it's better to put them at the end of page body. You can also achieve asynchronous loading by adding script dynamically:

var script = document.createElement("script");
script.type = "text/javascript";
script.src = "file.js";
document.body.appendChild(script);

You can even specify the loading chain: which script loads after which.

If your application comprises time-consuming processes, consider to perform them asynchronously, so that the application will not have to wait for them:


var runAsynchronous = function( fn, onCompleteCb ) {
        window.setTimeout(function() {
            fn();
            onCompleteCb();
        }, 0);
    }, 
    sleep = function( ms ) {
      var date = new Date(), curDate = null;
      do { 
          curDate = new Date(); 
      } while ( curDate - date < ms );
    }, 
    consumingFn = function() {
        sleep( 500 );    
    };

runAsynchronous( consumingFn, function() {
    console.log( "The process is complete" );
});
console.log( "The process is running" );

Conclusion

The article neither covers the programming patterns nor teaches JavaScript language. My intention was to show briefly the essential techniques, most commonly used in JavaScript. Something I would have liked to have a few years ago for myself. Since you've read this so far, you must be eager to evolve. That means, on your way to be a better JavaScript coder, you will read books, watch presentations, taking part in master-classes and study code. And everywhere you will meet these simple tricks I pointed in here. I hope you won't stumble over them now, but will be ready to follow the authors in more complicated solutions.