48

When using strings as keys of an array, console is showing that the array without these declared values and while iterating by this values where keys are string aren't displayed? , although i can get value of them.

>> var arr = [ 0, 1, 2, 3 ];
   undefined

>> arr["something"] = "aught";
   "aught"

>> arr
   [0, 1, 2, 3]

>> arr["something"]
   "aught"

>> for( var i = arr.length; i--; console.log( arr[ i ] ) );
   3
   2
   1
   0

I understand that arrays are objects which has implemented some kind of 'enumerate' interface in JavaScript's engine.

Most interesting is that interpreter isn't throwing either warning or error, so I spent some time of searching for where data could be lost.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
abuduba
  • 4,986
  • 7
  • 26
  • 43

2 Answers2

104

In javascript there are 2 type of arrays: standard arrays and associative arrays

  • [ ] - standard array - 0 based integer indexes only
  • { } - associative array - javascript objects where keys can be any strings

So when you define:

var arr = [ 0, 1, 2, 3 ];

you are defining a standard array where indexes can only be integers. When you do arr["something"] since something (which is what you use as index) is not an integer you are basically defining a property to the arr object (everything is object in javascript). But you are not adding an element to the standard array.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 2
    @abuduba, because there is nothing wrong :-) Your code is perfectly valid javascript. It's ambiguous to the reader since you are mixing the 2 type of arrays but it is valid. Why would you want the interpreter to indicate that something is wrong when there is nothing wrong. – Darin Dimitrov Dec 25 '11 at 16:44
  • 35
    This is mostly a terminology issue, but javascript does NOT generally call `{}` an associative array. They call it an object that has properties. Don't most people agree that it's best not to confuse things by calling a javascript object an associative array? – jfriend00 Dec 25 '11 at 16:46
  • 1
    Note: If you try to use ``defineProperty`` on the array like ``Object.defineProperty.call(arr,'something','aught');`` it will throw an error. – David Hellsing Dec 25 '11 at 16:47
  • You`re right. Key something is property of object instead index of array => `arr.something`. Maybe I'am too long without sleep .. I forgot that. Thanks @David - Nice, i did`nt know about it – abuduba Dec 25 '11 at 16:50
  • 3
    It's really strange because in console, `var a = []; a['test'] = ""; a;` displays `['test': ""]` therefore `a.length` is empty as expected. Also it's strange because if we add something like this `a[0] = 0;` both keys 'o' and 'test' has a property of 'a', It's hard to understand! – Jean-Luc Barat May 03 '17 at 11:09
16

for( var i = arr.length; i--; console.log( arr[ i ] ) );

This will only give you the numeric indices, of course, but you can still loop over both numeric indices and string keys of your array like this:

for (var x in arr) {
    console.log(x + ": " + arr[x]);
}
/* (console output):
     0: 0
     1: 1
     2: 2
     3: 3
     something: aught
*/
fanaugen
  • 1,107
  • 2
  • 10
  • 22