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.
- 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.- 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. - 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 ==
[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.
> 0 == false true > 1 == true true > 2 == true false > 2 ? true : false true // because 2 !== 0Equality 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
No comments:
Post a Comment