简体   繁体   中英

How does Type Coercion in Javascript in the case of object to boolean?

To the best of my knowledge, (x == false) should do the same thing as !x , as both of them try to interpret x as a boolean, and then negates it.

However, when I tried to test this out, I started getting some extremely strange behavior.

For example:

false == [] and false == ![] both return true.

Additionally

false == undefined and true == undefined both return false, as does

false == Infinity and true == Infinity and

false == NaN and true == NaN .

What exactly is going on here?

http://jsfiddle.net/AA6np/1/

It's all here: http://es5.github.com/#x11.9.3

For the case of false == [] :

  • false is converted to a number (0), because that is always done with booleans.
  • [] is converted to a primitive by calling [].valueOf().toString() , and that is an empty string.
  • 0 == "" is then evaluated by converting the empty string to a number, and because the result of that is also 0, false == [] is true.

For the case of false == ![] :

  • The logical not operator ! is performed by returning the opposite of ToBoolean(GetValue(expr))
  • ToBoolean() is always true for any object, so ![] evaluates to false (because !true = false ), and therefore is false == ![] also true.

(false == undefined) === false and (true == undefined) === false is even simpler:

  • false and true are again converted to numbers (0 and 1, respectively).
  • Because undefined cannot be compared to a number, the chain bubbles through to the default result and that is false .

The other two cases are evaluated the same way: First Boolean to Number, and then compare this to the other number. Since neither 0 nor 1 equals Infinity or is Not A Number, those expressions also evaluate to false .

The abstract equality algorithm is described in section 9.3 of the specification .

For x == y where x = false and y = [] :

  1. Nope. Types are not equal.
  2. Nope, x is not null.
  3. Nope. x is not undefined.
  4. Nope, x is not a number
  5. Nope, x is not a string.
  6. Yes, x is a boolean, so we compare ToNumber(x) and y.

Repeat the algorithm, x= 0 and y= [] .
We end at step 8:Type(x) == number. and Type(y) == object.
So, let the result be x == ToPrimitive (y).
ToPrimitive([]) == ""

Now, repeat the algorithm again with x= 0 and y= "" . We end at 4: "return the result of the comparison x == ToNumber(y)."
ToNumber("") == 0

The last repetition of the algorithm ends at step 1 (types are equal). By 1.c.iii, 0 == 0, and true is returned.

The other results can be obtained in a similar manner, by using the algorithm.

false == []

Using == Javascript is allowed to apply conversions. The object will convert into a primitive to match type with the boolean, leaving an empty string. The false will convert into a number 0. The compares the empty string and the number 0. The string is converted to a number which will be 0, so the expression is "true"

![]

Javascript converts the object to the boolean true, therefore denying true ends being false.

false == undefined true == undefined
false == Infinity and true == Infinity
false == NaN and true == NaN

Again a bit of the same! false is converted to 0, true to 1. And then, undefined is converted to a number which is... NaN! So false in any case

I would recommend to use === !== as much as you can to get "expected" results unless you know very well what you are doing. Using something like Boolean(undefined) == fals e would also be nice.

Check ECMAScript specifications for all the details when converting stuff.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM