

Fun with JavaScript Arrays - bubersson
http://blog.mikota.cz/2013/06/fun-with-javascript-arrays.html

======
residualmind
TBH, all those pose nothing really unexpected. It all makes sense. I was a
real JS hater, too - just because I didn't understand the language and I would
have laughed at those examples - until I watched "Crockford on JavaScript."
It's an interesting, entertaining, educating, (quite longish) series you
should treat yourself to. And just as drostie said, given the way the language
was born, it's really an amazing thing. And yes, it does have ugly parts.

~~~
lucian1900
I think I understand the language quite well and I still think it's terrible.
Knowledge does not preclude disapproval.

------
SandB0x
Bear in mind that I know very little JavaScript so I may be completely wrong
or this may be a very simple observation, but isn't the confusion in the first
part simply due to the printed representation of the Array prototype/object?

I seem to remember that arrays in JavaScript are in theory just objects/dicts
such that:

    
    
        var a = [1, 2, 3];
    

is equivalent to

    
    
        var a = {0 : 1, 1: 2, 2: 3};
    

and whatever function is invoked by evaluating `a` in the console must just
iterate over the sorted keys of the object, starting at key = 0 and attempting
to print key + 1 until the key does not exist. So he may be setting `a[-1]`
and it happily exists, but the confusion is just down to the whatever the
equivalent of the `__repr__` function is for JavaScript arrays.

~~~
jdlshore
Yes, most of the confusion is the author's misunderstanding of how arrays work
in JS, combined with his tool not showing everything he put into the array.

You're correct that arrays are objects, which means they consist key/value
pairs. Keys must be strings; values can be anything. So when you say `a[0] =
3;`, JS converts that to `a["0"] = 3;` and stores `{ "0": 3 }`.

So all those "funny" examples the author provides are just variants on
converting an expression to a string. For example, `a[typeof a] = 4` is
equivalent to `a["object"] = 4` (or `a.object = 4`) because `typeof a` is
"object".

There's one wrinkle on this, though: objects and arrays aren't exactly the
same thing. Arrays are a special kind of object, as far as JS is concerned. JS
maintains a special "length" property for arrays. It doesn't do that for other
objects.

(The same applies to JS functions and Regexes. They're objects, but they're
special kinds of objects that can do things regular objects can't.)

~~~
gambler
_Yes, most of the confusion is the author 's misunderstanding of how arrays
work in JS, combined with his tool not showing everything he put into the
array._

There is nothing in the post that shows that author doesn't know how arrays
are represented internally. Moreover, whether or not he does is largely
irrelevant. He shows clear examples of bad language design, and they remain
such whether you're aware of the inner workings of the language or not.

JavaScript's arrays have issues that span far beyond mere "string
representation". For example, you can't safely use for...in construct to
iterate over items in an array.

~~~
cristiantincu
The `for … in` statement iterates over the enumerable properties of an
object¹. It’s not for arrays.

1\. [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Statements/for...in)

------
SEJeff
I can't believe no one has posted the (in)famous WAT ruby/javascript
presentation:
[https://www.destroyallsoftware.com/talks/wat](https://www.destroyallsoftware.com/talks/wat)

It describes many ridiculous things in javascript such as empty array + empty
array == empty string, etc. It is also great for a good laugh to anyone who
has ever written javascript or ruby.

~~~
nandhp
Many of those examples also make sense when you consider what you're actually
asking for.

For example, Arrays have no + operator. So []+[] requires that [] be converted
to a string first. The string representation of [] is "" (although some
interpreters use "[]" or "[Array]" for clarity), so []+[]==""+""=="".

Similarly, he used the example []+{}, and claimed it was [object Object]. This
actually wrong (at least in Chrome); it's actually "[object Object]", a
string. The reason for this is the same as the previous example.

However, there is a different reason why {}+[]==0, given that "[object
Object]"+[] == "[object Object]". There turns out to be something special
about {} at the beginning of a statement (It's a block, or something). Thus,
{}+[] is like {};+[], where +[] causes [] to be converted to a _number_ : 0.
Compare: {}=={} (syntax error, unexpected token ==). Yes, this one is actually
confusing. (However, expressions are not usually evaluated in void context.)

He also observes that ",,,,,,,,,,,,,,," is a bad representation of Array(16).
It is, since the undefined in each element is important, but again, that can
be solved by using an interpreter with better string generation. (Or a version
of IE that doesn't attempt to be clever and just returns "[Object]" all the
time).

So perhaps the moral of the story is: Yes, it's an entertaining talk, but a
several of the examples break down because his interpreter is vague.

------
jhaglund
Assignment within the brackets, that kinda surprised me

    
    
      > a = []
      > a[a[typeof a]='huh', void a] = 'puh'
    
      > console.log(a)
      [object: "huh", undefined: "puh"]
    

huh... you can do this too

    
    
      > a = []
      > a[a[a[typeof a]='huh'] = 'puh'] = 'woh'
      > console.log(a)
      [object: "huh", huh: "puh", puh: "woh"]

~~~
Tloewald
The comma operator in Javascript is a major WTF. The entire post basically
comes down to a, b evaluates to b, [] coerces to string, and arrays are
objects.

The only thing to really look bad is chrome, which is surprisingly easy to
kill.

------
hcarvalhoalves
You don't have to stretch it beyond normal tasks to get some big WTFs:

[https://gist.github.com/hcarvalhoalves/4471029](https://gist.github.com/hcarvalhoalves/4471029)

~~~
Wilya
sort() is a bit weird, I have to agree, but the '==' thing is a common problem
to a lot of languages, not exactly a js-specific WTF.

Off the top of my mind:

In Python, '==' on arrays compares elements.

In Java, '==' on arrays compares the objects themselves. You have to use
equals() to compare the elements.

In C(++) arrays, '==' compares the objects. But for std::vector, it compares
the elements.

One could argue it's a language choice more than a screwup.

~~~
arethuza
Common Lisp has quite a few equality functions: eq, eql, equal, equalp

[http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node74.html](http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node74.html)

------
Kiro
Once you realize that there are no associative arrays in JavaScript these
things become less of a WTF.

~~~
dkroy
Couldn't some JavaScript Objects be called associative arrays?

~~~
Skinney
Not really no. Every object has it's prototype set to the object prototype.
Which means that even if you create a new empty object, it inherits functions
and values from the object protype.

var a = {}; typeof(a.hasOwnProperty) === "function"

Objects are very often used as associative arrays, quite simply becouse
objects and arrays are all js has to offer. Javascript Harmony will change
that though, with it's own Map type.

~~~
spirit23
Not really. Actually you can create an empty object by: var a =
Object.create(null)

~~~
Skinney
oooo, shiny!

