Greg Charles wrote:I pretty much understand it, except how we can index elems with the square brackets, as in elems[0] and elems[1]. Does just having a length property enable that?
It may appear that somehow elems is magically being turned into an array, but it's not. Remember that the square bracket notation can also be used to reference properties, not just array indexes. What is actually happening is that the call to Array.prototype.push in the add() method is creating numbered properties on the object rather than doing a real array push.
You can see this best by setting a breakpoint at line 21 of the example code (line 6 in your posted code):
Before the line is executed for the first time, the elems object is:
{length: 0, add: function, gather: function}
and after stepping over the call to push:
{0: input#first, length: 1, add: function, gather: function}
notice that a property with name "0" has been added, and the length incremented.
After the second call to push, we see:
{0: input#first, 1: input#second, length: 2, add: function, gather: function}
in which the property "1' has been added.
So the object isn't really being turned into an array, it's just being treated like one. Externally, it's not evident because elems[n] acts the same regardless of whether n is a property or array index.
This, per se, isn't anything very useful -- the point of the example was simply to show how the prototyped functions of object such as Array can be leveraged in other objects without having to
be an array.