Reputation: 55759
Why does the following enumerate correctly?
var arr = [];
arr[0] = 'foo';
arr['1'] = 'bar';
arr.forEach(v => console.log(v)); // foo, bar
Both arr[1]
and arr['1']
also work. Is this a feature of Array
that strings corresponding to integers are mapped to their integer value?
Upvotes: 4
Views: 60
Reputation: 125561
Is this a feature of Array that strings corresponding to integers are mapped to their integer value?
No. Think of Arrays just like regular objects.
When accessing a property of an object using bracket notation - the property must be quoted.
eg: var someVar = { a:1, b:2 }
- to access the value of property 'a' with bracket notation we write: someVar['a']
So it makes perfect sense to access array elements via quoted indexes.
That being said, it isn't necessary to quote the index - and that's because - as others have mentioned - the index is coerced into a string by the JavaScript engine through an implicit toString conversion
Upvotes: 1
Reputation: 7480
It's due to the fact that arrays in Javascript are just objects with some dedicated syntactic sugar.
Compare:
var arr = [];
arr[0] = 'foo';
arr['1'] = 'bar';
console.log(arr['0']);
console.log(arr[1]);
... to:
var obj = {};
obj[0] = 'foo';
obj['1'] = 'bar';
console.log(obj['0']);
console.log(obj[1]);
Basically, Array
is a type of Object
, with array specific methods and non-enumerable properties, such as length
, which can be instantiated with the dedicated shorthand syntax [ items... ]
The indices of an array are actually strings, just like all keys in any object, it works because referencing an object property using a number as a key will coerce that number into its string representation (in principle, that is. I assume most modern browsers have internally optimized this heavily).
Example:
var obj = {};
obj[1.5] = 'foo';
console.log('1.5' in obj);
console.log(obj[1.5]);
var arr = [];
arr[0.5] = 'foo';
console.log('0.5' in arr);
console.log(arr[0.5]);
arr[0] = 'bar';
arr[1] = 'baz';
console.log(arr.length);
console.log(Object.keys(arr));
Upvotes: 2
Reputation: 6557
For those questions, It may be worth taking a look into the specification
Array objects give special treatment to a certain class of property names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^(32)−1
Thus, because:
parseInt("1").toString() === "1"
"1" is a perfectly valid array index.
See http://www.ecma-international.org/ecma-262/5.1/#sec-15.4
EDIT: One might ask "What's with 1 (a number)", because parseInt(1).toString()
is not equal to 1 (but "1", a string). I think the answer to this is the part "(in the form of a String value)", so I believe 1 is first interpreted as "1" before applying those rules.
Upvotes: 1