Free email newsletter: “ES.next News

2013-08-20

Why all objects are truthy in JavaScript

In JavaScript, all objects are truthy [1], even new Boolean(false), empty arrays and empty objects:
    > Boolean(new Boolean(false))
    true
    > Boolean([])
    true
    > Boolean({})
    true
That is different from how objects are converted to number and string, where you can control the result by implementing the methods valueOf() and toString() [2].

Why converting to boolean is different

The conversion to boolean is different for historic reasons: For ECMAScript 1, it was decided to not allow objects to configure that conversion. The rationale was as follows. The boolean operators || and && preserve the values of their operands. Therefore, one may have to coerce the same object several times. That was considered a performance problem and led to the rejection.

As an example, let’s assume that new Boolean(false) coerces to false and use it in an expression:

    new Boolean(false) && 1 && true
That expression is evaluated in two steps:
    new Boolean(false) && 1    → new Boolean(false)
    new Boolean(false) && true → new Boolean(false)
For each step, you need to coerce new Boolean(false) to boolean in order to determine the result.

The exception to the rule

Some browsers have the (deprecated) property document.all that is quite weird. For example, the following is an interaction in Google Chrome’s console:
    > {}.toString.call(document.all)  // an object
    '[object HTMLAllCollection]'
    > Boolean(document.all)  // falsy!
    false
    > typeof document.all  // strange!
    'undefined'

References

  1. JavaScript quirk 1: implicit conversion of values
  2. What is {} + {} in JavaScript?

No comments: