Reputation: 44776
I know JavaScript has lots of insane results with comparisons between types, though I don't fully understand why. Came across this one today.
Why does
"" == [null]
evaluate to true
in JavaScript?
Some more Javascript equality amusement, thanks to @Qantas:
Upvotes: 54
Views: 5157
Reputation: 66304
Let's look at the spec and follow through each step
Going via the Abstract Equality Comparison Algorithm (§11.9.3):
typeof ""; // string
and typeof [null]; // object
so not applicablenull
or undefined
so not applicableToPrimitive([null])
§9.1 ToPrimitive for Objects says we need to work out [[DefaultValue]]
(§8.12.8), points 1 and 2 of which say if you can do .toString
and it gives a string, return that, so
[null].toString(); // ""
So we are now performing the comparison "" == ""
which is true
by the Abstract Equality Comparison Algorithm's point 1. d.
If
Type(x)
is String, then returntrue
ifx
andy
are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, returnfalse
.
Upvotes: 2
Reputation: 5695
The value null is a JavaScript literal representing null or an "empty" value, i.e. no object value is present. It is one of JavaScript's primitive values.
The value null is a literal (not a property of the global object like undefined can be). In APIs, null is often retrieved in place where an object can be expected but no object is relevant. When checking for null or undefined beware of the differences between equality (==) and identity (===) operators (type-conversion is performed with the former).
typeof null // object (bug in ECMAScript, should be null)
typeof undefined // undefined
null === undefined // false
null == undefined // true
Upvotes: -1
Reputation: 102743
It's according to the arcane type-conversion rules of Javascript. Rule #8:
If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
So the comparison is between x = ""
and y = [null]
converted to a string using ToPrimitive
. Converting an array with one null element results in an empty string (because Array.toString()
returns a comma-separated list of values), hence they evaluate to equal.
Upvotes: 17
Reputation: 413712
The "Abstract Equality Comparison Algorithm" has many parts, but the important one here is this:
If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
(There's a mirror-image of that too.) So, because ""
is a string and [null]
is an object, we've got to first convert [null]
to a string by calling ToPrimitive([null])
. That's an internal operation described as follows, when it's asked to convert an Object instance to a primitive value:
Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.
Now, the [[DefaultValue]] internal operation will call .toString()
on the object and return that value. Try [null].toString()
in your browser console:
> [null].toString()
""
And there you have it.
Edit: And why is [null].toString()
an empty string? Because the .toString()
operation on Array instances always just calls .join()
, and that always yields an empty string for null
and undefined
values. Thus an array of one null
ends up as just a single empty string.
Upvotes: 76
Reputation: 19
JavaScript is weakly typed; you can use the following to get a false result:
"" === [null]
Upvotes: 1
Reputation: 664307
Why does
"" == [null]
evaluate to true?
Because you're comparing an array with a string, using the non-strict equality operator ==
- so it will try to cast values to the same type before comparing them.
What happens in detail is:
.toString()
method is invoked (as explained in detail by the other answers), which is equivalent to calling .join()
:undefined
or null
value returns the empty stringThis third step is the unexpected one ([null]+"" != null+""
), if it actually did cast that to a string the result would have been "null"
and your equality be false.
Upvotes: 12