1

Inspired by Lance Pollard's comment in this question, something really weird happened and I have never seen this before...

var strangeArray = {
    0:"a",
    1:"b",
    2:"c",
    length: 0,
    splice: Array.prototype.splice
}

Now, when you run it:

> strangeArray;
  []    <-- you get an empty array.

> strangeArray.length;
  0     <-- Holy $#!T

And now:

> strangeArray[0];
  "a"

> strangeArray[1];
  "b"

> strangeArray[2];
  "c"

What the? "Hidden values in an array"?

First I thought because it is an object, that's why. But object should show like this:

{}

So why is this happening? Please help, I am totally confused. Thanks.

Community
  • 1
  • 1
Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247

3 Answers3

4

It's just the way consoles often interpret an Object as an Array (even if it isn't an Array at all, as in your code).

When the console sees an object with...

  • a numeric .length property
  • a function .splice property

...the console decides to display it as an Array, even if it isn't. It has no effect on what the object actually is.

strangeArray.length; // 0

This should be no surprise. You defined it on the object.

The reason they use this approach is presumably because it's fast, and sufficiently accurate.

Once again, just because you see [], doesn't mean it's an Array. The console is not part of the language. It just has the job of displaying some useful information.

  • @Derek: `[]` isn't something you typed into your JS code to be interpreted by the JS engine. In your case `[]` is just some text being displayed in the console. Again, the console is not part of the language. A developer console can display whatever it wants, and it wouldn't be breaking any rules... because there are none. –  May 26 '12 at 03:01
  • ...let me put it this way. If some rogue console developer decided to display `[]` every time it received the number `42`, would that make the number `42` an Array? Of course not. It's still a number, but the console decided do display it as though it was an Array, irrespective of what it actually is. –  May 26 '12 at 03:06
3

strangeArray.length == 0 because you explicitly set strangeArray.length to be the integer 0, overriding its default value.

The array still contains elements:

for (var i in strangeArray) {
  console.log(i);
}

Outputs:

0
1
2
length
splice
Blender
  • 289,723
  • 53
  • 439
  • 496
  • 1
    But why it displays `[]` instead of something else? – Derek 朕會功夫 May 26 '12 at 02:48
  • Set `strangeArray.length = 1` and see what happens. I'm guessing that the JavaScript compiler checks for the length of the array before displaying it. – Blender May 26 '12 at 02:50
  • 1
    Now try `100` instead of `1` ;) – Blender May 26 '12 at 02:51
  • @Derek: Because it's still an array. It didn't change what it was just because you overrode its properties. This is actually an example of ambiguous code on your part. You shouldn't be specifying the length property as its already defined for arrays. Also, just because it's an array doesn't mean it's not also an object with its own properties. – Joel Etherton May 26 '12 at 02:51
  • @JoelEtherton: It is not an Array. It's purely an Object. –  May 26 '12 at 02:52
  • @am not i am, Isn't an array *is* an object? – Derek 朕會功夫 May 26 '12 at 02:52
  • 1
    @Derek: Yes, but an Object is not necessarily an Array. The Object in your question is not an Array. –  May 26 '12 at 02:53
  • It's not entirely clear *how* the objects are printed out in the console. Somehow the compiler iterates over the object by utilizing its `.length` property. If that property is set, then the object is considered an array and printed as such *only by the printing function of the compiler*. What you see isn't what is actually there. A JavaScript mirage. – Blender May 26 '12 at 02:55
  • @amnotiam: It became an array (sort of) when he added the prototyping (ref: http://www.hunlock.com/blogs/Mastering_Javascript_Arrays) – Joel Etherton May 26 '12 at 02:56
  • @JoelEtherton: Not really. You could add an empty function, and it would show up the same. It's only an Array if it inherits from `Array.prototype`. This object doesn't do that. You could call it an Array-like object, but there's no real definition of what that means. –  May 26 '12 at 02:57
0

Everything is an object in javascript. See the answer to the following question for a detailed explanation:
How is almost everything in Javascript an object?

Given that, the community wiki answer provides the rest of the explanation. Since you give your strangeArray object properties normally associated with an array object, you trick the console into displaying it as such.

Community
  • 1
  • 1
christurnerio
  • 1,469
  • 11
  • 13