Some time ago I was doing exercises on codwars (which btw. I really recommend) and encountered interesting problem.

Implement a version of range the way that it should return an array containing ‘count’ numbers from ‘start’ to ‘start + count’.

Example: Array.range(0, 3) returns [0, 1, 2].

It doesn’t sounds difficult so my first thought was this:

Array.range = function(start, count) {
  return new Array(count).map(function(i) { return start + 1});
};

After I was done with that one line of code, I run it and I was really surprised with the result:

Array.range(1,5) // [undefined × 5]

As I dig into it, it turned out that the map function is not being called after new Array is created. To see what new Array(n) does I played with the console:

var array = new Array(3);
array // [undefined × 3]
console.log(array) // []
array[1] // undefined
array.length // 3

array.length = 5
array // [undefined × 5]

So what we actually get with new Array(3) is an Array object whose length property is set to the size parameter passed to the constructor. When we try to call map function on our array the callback function is not executed because array doesn’t have any values inside (even the size is > 0).

So how can we create array with fixed size that we can loop through its elements?

Array.apply(null, new Array(5))

var array = Array.apply(null, new Array(3));
array // [undefined, undefined, undefined]

What’s the difference? Let’s revise what Function.prototype.apply() does:

The apply() method calls a function with a given this value and arguments provided as an array (or an array-like object). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

The main trick happens when array is provided to the apply method because it uses its length property to define a size of a new array which clones all the values of the original one.

If you are more interested you can check the Annotated ECMAScript 5.1, the cloning process is in step 8:

Repeat while index < n:

  1. Let indexName be ToString(index).
  2. Let nextArg be the result of calling the [[Get]] internal method of argArray with indexName as the argument.
  3. Append nextArg as the last element of argList.
  4. Set index to index + 1.

That’s all for now.