Array.prototype contains many generic methods that can be applied to array-like objects. [] is a popular shortcut for accessing these methods. This post examines the pros and cons of using that shortcut.
Update: Inspired by a comment from Kevin Roberts, I’ve added a third way of accessing generic methods, and a conclusion.
Generic methods. Some methods are generic. While they are directly available to instances of their prototype, they can also be borrowed by other instances. To borrow a generic method, one invokes one of the following two methods on it:
Example: invoking Array.prototype.map() generically, on the array-like arguments object.
function prefixHello(prefix) { return Array.prototype.map.call(arguments, function(elem) { return "Hello "+elem; }); }Interaction:
> prefixHello("Jane", "John") [ 'Hello Jane', 'Hello John' ]
[] as a shortcut. [].foo is often used as a shortcut for Array.prototype.foo. That is, you access a prototype property via an instance.
var iterations = 100000000; var data = []; // empty so that slice() doesn’t have much to do (function () { var start = (new Date).getTime(); // loop var diff = (new Date).getTime() - start; console.log(diff); }());Timing prototype access:
for(var i=0; i<iterations; i++) { Array.prototype.slice.call(data); }Timing the shortcut:
for(var i=0; i<iterations; i++) { [].slice.call(data); }Storing the prototype in a local variable:
var arrayProto = Array.prototype; for(var i=0; i<iterations; i++) { arrayProto.slice.call(data); }Results (iMac, 2.7 GHz Intel Core i5):
iterations | prototype | shortcut | quick prototype | |
Node.js 0.4.8 | 100,000,000 | 5019ms | 5075ms | 4692ms |
Firefox 6 | 10,000,000 | 1592ms | 2237ms | 1522ms |
Rhino 1.7 release 3 | 10,000,000 | 2318ms | 2687ms | 1878ms |