I just read this article and there is this expression:
(!+[]+[]+![]).length
Evaluating this in the interpreter:
> (!+[]+[]+![]).length
9
Well, why?
I just read this article and there is this expression:
(!+[]+[]+![]).length
Evaluating this in the interpreter:
> (!+[]+[]+![]).length
9
Well, why?
Walkthrough:
+[] === 0
!+[] === true
!+[]+[] === "true"
(!+[]+[])+![] === (!+[]+[])+false === "truefalse"
"truefalse".length === 9
There are several type constraints that ultimately cause this result. Detailing the first line above:
+[] ⟶ +"" ⟶ 0
So we have:
!+[] ⟶ !0 ⟶ !false ⟶ true
Moving on:
!+[]+[] ⟶ true + [] ⟶ true + "" ⟶ "true"
This "true"
will be concatenated with:
![] ⟶ !true ⟶ false
Therefore:
"true" + false ⟶ "truefalse"
I read the article and was disappointed. It's alright that it's already been a cliche to say that JS sucks , wat a>, but it has some unfair criticism. So I'll list some points here in defense of the language:
When attempting to make comparisons between certain types (such as array and object), the language might even throw an exception. But for me the real WTF is the programmer doing something like {} > []
or ![]
and waiting for a response that makes sense ... The language opted for type coercion , and the rules of this are necessarily arbitrary .
It is not strange that the type of NaN
is number, since NaN
is defined in the floating-point number (IEEE 754) arithmetic standard
"string" instanceof String === false
because there is a difference between primitive values of type string and objects of type String. In Java it looks similar, does not it?
Claim that 0.1+0.2!==0.3
is basic knowledge of floating-point arithmetic in almost any language.
Claim 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 rather between the past. If you do not do anything, max
returns -Infinity
, which makes some sense.
I could say more, but I'll stop here ...