Equality in JavaScript
Update 2011-12-02: When is it OK to use == in JavaScript?
There are two operators for comparing values in JavaScript: strict equality === and “normal” (or lenient) equality ==. Many style guides (correctly) tell programmers to avoid lenient equality and always use strict equality. This post explains why.
Where appropriate, related sections in the ECMAScript 5 language specification [1] are mentioned in square brackets.
Two ways of comparing
- The strict equality operator === only considers values equal that have the same type.
- The lenient equality operator == tries to convert values of different types, before comparing like strict equality.
Lenient equality causes two problems:
- The conversion rules are counter-intuitive and do things you might not expect.
- As the operator is so forgiving, type errors can remain hidden longer.
Strict equals ===
[ES5 11.9.6] Comparing two values. Values with different types are never equal. If
both values have the same type then the following assertions hold.
Examples:
> var a = NaN;
> a === a
false
> var b = {}, c = {};
> b === c
false
> b === b
true
> "abc" === new String("abc")
false // different types (left: primitive, right: object)
Equals ==
[ES5 11.9.3] Comparing two values. If both values have the same
type: compare with
===. Otherwise:
- undefined == null
- One number, one string: convert the string to a number
- A boolean and a non-boolean: convert the boolean to a number and
then perform the comparison.
- Comparing a string or a number to an object: try to convert the
object to a primitive and then make the comparison.
(3) leads to a weird idiosyncrasy where numbers
greater than 1 are true in
if statements, but not equal to
true:
> 0 == false
true
> 1 == true
true
> 2 == true
false
> 2 ? true : false
true // because 2 !== 0
Equality and strings:
> "" == 0
true
> "123" == 123
true
> "" == false
true
> "1" == true
true
> "2" == true
false
> "true" == true
false
> "2" ? true : false
true // because string is non-empty
> "abc" == new String("abc")
true // right side converted to primitive
Related reading
- ECMAScript Language Specification, 5th edition.
- JavaScript values: not everything is an object