Here is a good question :-) Roughly speaking, an array is an object with a length
property, a set of properties labeled from 0
to length - 1
, and a couple of specific features. We could almost say that a = [1, 2, 3]
is a shortcut for :
a = { 0: 1, 1: 2, 2: 3, length: 3 }
In fact, you can easily simulate an array using a plain object.
An object is a collection of key-value pairs, like a dictionary. A key can be any arbitrary string, and a value can be any type of data. In JavaScript, almost everything is an object. An array is an object, a function is an object, even atomic data like numbers and strings can be manipulated like an object, indeed, JavaScript secretly creates an object in order to wrap the atomic data.
There are a couple of ways to create an object. Often you'll see either the literal notation based on brackets ({}
and []
) or the new
keyword. The literal notation is just syntactic sugar, in fact, your computer executes the exact same sequence of instructions in both cases. In other words, o = {}
is the same as o = new Object()
, and a = []
is the same as a = new Array()
.
Yes, when you write a = []
, you are implicitely creating an instance of the Array
class, this is what makes an array a special object :-) As stated above, an array is an object with additional features, and these features are inherited from the Array
class. The indexOf
method is one of them (type Array.prototype
in a console to list them all) :
var a = ["a", "b", "c"];
a.indexOf("b"); // 1
Until recently, as long as you didn't call Array
specific methods from the object itself, you could easily cheat on JavaScript by adding a length
property to a plain object and use it as an array. JQuery takes advantage of this technique : http://api.jquery.com/Types/#ArrayLikeObject.
var o = { length: 0 };
Array.prototype.push.call(o, "a", "b");
console.log(o, Array.prototype.slice.call(o));
Today this is a little harder to achieve, for example, you have to implement an iterator to be able to use a plain object in a for ... of
loop :
var o = {
0: "a",
1: "b",
2: "c",
length: 3
};
// o[Symbol.iterator] = Array.prototype[Symbol.iterator];
// works as well, but I want you to see there is no magic :-)
o[Symbol.iterator] = function() {
return {
i: 0,
o: this,
next: function() {
var o = this.o;
var i = this.i++;
return {
value: o[i],
done: i === o.length
}
}
};
};
for (var x of o) {
console.log(x);
}
for (var x in o) {
console.log(x, o[x]);
}
Note that JavaScript ignores the length
property of a true array in a for ... in
loop. In my humble opinion this is a questionable choice that is most likely to cause a blue screen in the brain of the candid newbie...
var a = [1, 2, 3];
a["i'm"] = "your father";
console.log("length", a.length);
for (var k in a) {
console.log(k, a[k]);
}
Final word, don't get confused by the output of the Chrome's console, the way it displays arrays is an arbitrary choice of Google developers. Look, printing things has nothing to do with writing source code, indeed, you have the power !
printArray([1, 2, 3]);
function printArray(a) {
console.log("["
+ a.join(", ") + ", "
+ "length: " + a.length
+ "]");
}
Further reading : https://stackoverflow.com/a/5048482/1636522.
a['foo']
it becomes a hybrid. Not a good thing to do if you don't know what you are doing with an "array like object" – charlietflconsole.log
is simply a choice of the browser/environment. Node.js and Chrome DevTools will print[ 1, 2, 3, foo: 'bar' ]
, for example. – voxconsole.log
does not necessarily print out valid JavaScript. It is for display purposes only.console.log( Object.assign( {}, a ) );
would give you a valid object, however. Note it wouldn't be an Array. – vox