strawman: better ToBoolean
In ES3 and ES5, a number of operations (such as if(foo)
) call an internal ToBoolean
algorithm. The return value of ToBoolean
is defined for each basic type:
- Undefined: false
- Null: false
- Boolean: no conversion
- Number: false if +0, -0, or NaN; otherwise true
- String: false if "", otherwise true
- Object: true
The semantics of three of these, +0, -0 and "", significantly complicate JavaScript programs. For instance, it makes it impossible to use a bare if statement to differentiate null or undefined expressions from Number values. In general, it is useful to differentiate null values from valid user-supplied values. Many examples of this phenomenon can be find by searching the jQuery project (or any other large JavaScript project) for if(someval == null)
in cases where zero is a valid value.
As this proposal changes ES3 semantics, it requires an opt-in:
"use cafe-boolean-coercion";
Change the values defined in Section 9.2 or ES5 to:
- Undefined: false
- Null: false
- Boolean: no conversion
- Number: false if NaN; otherwise true
- String: true
- Object: true
The ES5 spec references a number of uses of ToBoolean. This proposal does not change any of those references, it just changes the meaning of ToBoolean
. In all cases, it is possible to translate an expression that would semantically invoke ToBoolean into:
expr || expr === 0 || expr === ""
In some cases, it may be desirable to store the value of expr in a local variable to eliminate repeated work:
var __expr__ = expr;
__expr__ || __expr__ === 0 || __expr__ === ""