Real World JavaScript – Part 1

Strict Mode

Strict Mode as specified in ECMAScript Standard 5 is a way to use only the good parts of the JavaScript. Strict mode code will be run with different behavior in those supported browsers. The three obvious benefits are

1. Will make some silent errors to scream causing their early detection
2. Strict mode makes the code more optimization friendly for the JavaScript engines
3. Strict mode prohibits the usage of some likely future JavaScript syntax

One way to invoke strict mode is to put the following statement as the first statement1 of an entire script. This is the exact way used in AngularJS. This way known as strict mode for scripts has the disadvantage that strict mode and non-strict mode files could not be combined. You can also take the approach of wrapping the entire contents of a script in a function and having that outer function use strict mode. This eliminates the concatenation problem but it means that you have to explicitly export any global variables out of the function scope.

"use strict";

Another way to invoke strict mode is to put the exact statement “use strict”; in the function’s body before any other statements. This is called strict mode for functions and is the method used by the Bootstrap team. MSDN document on javasript strict mode details the restrictions applied in strict mode.

call method usage in higher order functions

Let’s take the simplest example from UnderscoreJS, the each method. It iterates over a list of elements, yielding each in turn to an iterator function. The iterator is bound to the context object, if one is passed. The common practice is to take an optional receiver object by the higher order function. Its entire source code is as follows

var each = _.each = _.forEach = function(obj, iterator, context) {
    if (obj == null) return;
    if (nativeForEach && obj.forEach === nativeForEach) {
      obj.forEach(iterator, context);
    } else if (obj.length === +obj.length) {
      for (var i = 0, l = obj.length; i < l; i++) {
        if (iterator.call(context, obj[i], i, obj) === breaker) return;
      }
    } else {
      for (var key in obj) {
        if (_.has(obj, key)) {
          if (iterator.call(context, obj[key], key, obj) === breaker) return;
        }
      }
    }
  };

The first argument to the call method is the object on whose context the function should run. In the above context the call method is invoked on the iterator function passing the optional context as the first parameter.

Immediately Invoked Function Expression2

There are different ways to execute a function expression immediately. A common convention is to enclose both the function expression and invocation in parentheses. Twitter Bootstrap’s JavaScript code shatters the convention and makes an anonymous function immediately invokable through the following code.

!function ($) {

  // code omitted for brevity


}(window.jQuery);

Unary operator in the above code makes the function statement an expression and it is invoked. The catch is return value of the function will be ignored and also code readabilty is lowered at the benefit of saving a few bytes.

Converting arguments to real array

Although arguments object inside a function could be accessed and set like an array it is not a real array. It does not have any real array properties except length3. arguments could be converted to real array using the slice method which creates a new array with the option to select the elements using the start and ebd indices.

var args = Array.prototype.slice.call(arguments);

invoke method in UnderscorJS uses the slice method on array prototype to convert the arguments to array and to exclude the first two arguments from the array. It then invokes the given method for each item and since it has to pass an array of arguments to the function it calls the apply method insted of call.

_.invoke = function(obj, method) {
    var args = slice.call(arguments, 2);
    var isFunc = _.isFunction(method);
    return _.map(obj, function(value) {
      return (isFunc ? method : value[method]).apply(value, args);
    });
  };

References & Footnotes

1 It is also ok to place it among the first set of similar declarative statements as strict mode

2 Immediately Invoked Function Expression

3 More about arguments in MDN

Javscript, the scripting language created in 10 days, has got a bag of tips, quirks, and patterns. This is part one of a series of articles (hopefully) on real world JavaScript usage. - Suhair
comments powered by Disqus