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.

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.

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 ===

undefined === undefined

null === null

Two (primitive) numbers: NaN !== _ // any value including NaN x === x +0 === -0 for any number x . Thus equality is not reflexive in JavaScript, because NaN is not equal to itself.

for any number . Thus equality is not reflexive in JavaScript, because is not equal to itself. Two booleans, two strings (primitive): obvious results

Two objects (including arrays and functions): x === y only if x and y are the same object(!). That is, if you want to compare different objects, you have to do it manually.

> 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 ==

===

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.

if

> 0 == false true > 1 == true true > 2 == true false > 2 ? true : false true // because 2 !== 0

> "" == 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

Lenient equality causes two problems:[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:[ES5 11.9.3] Comparing two values. If both values have the same type: compare with. Otherwise:(3) leads to a weird idiosyncrasy where numbers greater than 1 are true instatements, but not equal to true:Equality and strings: