Why (!+[]+[]+![]). length returns 9 in Javascript?

Asked

Viewed 722 times

67

I just read that article and in it there is this expression:

(!+[]+[]+![]).length

Evaluating this in the interpreter:

> (!+[]+[]+![]).length
9

Good, why?

1 answer

75


Step by step:

+[] === 0
!+[] === true
!+[]+[] === "true"
(!+[]+[])+![] === (!+[]+[])+false === "truefalse"
"truefalse".length === 9

It has several type coercions that ultimately cause this result. Detailing the first line above:

+[] ⟶ +"" ⟶ 0

So we have:

!+[] ⟶ !0 ⟶ !false ⟶ true

Moving on:

!+[]+[] ⟶ true + [] ⟶ true + "" ⟶ "true"

That one "true" will be concatenated with:

![]  ⟶ !true ⟶ false

Therefore:

"true" + false ⟶ "truefalse"


Relevant references of the specification:


About the article that you quoted

I read the article and I was disappointed. It’s okay that it has become a slogan to say that JS sucks, à la Wat, but there are some unfair criticisms. So I’ll list some points here in defense of language:

  • When trying to make comparisons between certain types (such as array and Object), the language could even throw an exception. But for me the real WTF is the programmer doing something like {} > [] or ![] and expect an answer that makes sense... Language has chosen to type coercion, and the rules of that are necessarily arbitrary.

  • It’s not strange that the kind of NaN be number, since NaN is defined in the floating point number arithmetic standard (IEEE 754)

  • "string" instanceof String === false because there is a difference between the primitive values of type string and objects of type String. In Java it is similar, no?

  • Complain that 0.1+0.2!==0.3 is basic knowledge of floating point arithmetic in virtually any language.

  • Complain that Math.max()<Math.min() is not having read any documentation about these methods. Their goal is not to return the maximum and minimum values understood by language, but between the past. If you pass nothing, max returns -Infinity, which makes some sense.

I could say more, but I’ll stop here...

  • JS and bizarre XP

  • It’s just that the mechanism of type coercion is not very intuitive, especially when we try to do things like use + between arrays. The language does not provide any special operation for this (such as joining the sets represented in the arrays), so there is conversion.

  • Besides being able to ! + [] what is very strange.

  • @Lucasvirgili But beware that the !+[] from the beginning is actually !(+[]) (that is, there is an array-to-number coercion, after that number for boolean).

  • 1

    I get it, @bfavaretto. I still think it’s something that should be an XD syntax error

  • 3

    I also think, @Lucasvirgili It makes no sense to convert array to number, deny array, etc.

  • I wish I could favorite answers, favorite this.

  • @Lucasvirgili I updated my answer by countering some points of the article you quoted.

  • 3

    There’s nothing you can do +[] be a syntax error, since + is a unary operator that accepts any expression. The best you could do is generate a type error, which in Javascript would appear as a runtime exception.

  • 1

    @hugomg True, but I think that’s what Lucas meant, to make an exception of some kind.

  • Most of what the guy actually says is much more "Wat" because it shouldn’t be tried anyway, @bfvaretto. Who am I to say that some language has a bad design when the ones I did were disgusting :P

  • 4
  • 7

    Of those JS oddities, my favorite is Array(16).join("lol" - 2) + " Batman!". You don’t even have to spin to know what’s coming out of it. : D

  • Yeah, somebody do {} > [] literally would be too weird. But this is just for visibility, because in practice people test two variables that can contain anything. Therefore, although it is extremely unlikely that someone will take the literal test, expressions are very common when we use variables mainly input parameters in methods.

  • @Brunoaugusto, I liked the "NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!". That sounds like music to the ears :)

Show 10 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.