The strict equality operator (===
) behaves identically to the abstract equality operator (==
) except no type conversion is done, and the types must be the same to be considered equal.
Reference: JavaScript Tutorial: Comparison Operators
The ==
operator will compare for equality after doing any necessary type conversions. The ===
operator will not do the conversion, so if two values are not the same type ===
will simply return false
. Both are equally quick.
To quote Douglas Crockford's excellent JavaScript: The Good Parts,
JavaScript has two sets of equality operators: ===
and !==
, and their evil twins ==
and !=
. The good ones work the way you would expect. If the two operands are of the same type and have the same value, then ===
produces true
and !==
produces false
. The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values. The rules by which they do that are complicated and unmemorable. These are some of the interesting cases:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
The lack of transitivity is alarming. My advice is to never use the evil twins. Instead, always use ===
and !==
. All of the comparisons just shown produce false
with the ===
operator.
Update
A good point was brought up by @Casebash in the comments and in @Phillipe Laybaert's answer concerning objects. For objects, ==
and ===
act consistently with one another (except in a special case).
var a = [1,2,3];
var b = [1,2,3];
var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };
var e = "text";
var f = "te" + "xt";
a == b // false
a === b // false
c == d // false
c === d // false
e == f // true
e === f // true
The special case is when you compare a primitive with an object that evaluates to the same primitive, due to its toString
or valueOf
method. For example, consider the comparison of a string primitive with a string object created using the String
constructor.
"abc" == new String("abc") // true
"abc" === new String("abc") // false
Here the ==
operator is checking the values of the two objects and returning true
, but the ===
is seeing that they're not the same type and returning false
. Which one is correct? That really depends on what you're trying to compare. My advice is to bypass the question entirely and just don't use the String
constructor to create string objects from string literals.
Reference
https://262.ecma-international.org/5.1/#sec-11.9.3
'' == '0' // false
The left hand side is an empty string, and the right hand side is a string with one character. They are false because it is making a comparison between two un identical strings (thanks Niall).
0 == '' // true
Hence, why this one is true, because 0
is falsy and the empty string is falsy.
0 == '0' // true
This one is a bit trickier. The spec states that if the operands are a string and a number, then coerce the string to number. '0'
becomes 0
. Thanks smfoote.
false == undefined // false
The value undefined
is special in JavaScript and is not equal to anything else except null
. However, it is falsy.
false == null // false
Again, null
is special. It is only equal to undefined
. It is also falsy.
null == undefined // true
null
and undefined
are similar, but not the same. null
means nothing, whilst undefined
is the value for a variable not set or not existing. It would kind of make sense that their values would be considered equal.
If you want to be really confused, check this...
'\n\r\t' == 0
A string consisting only of whitespace is considered equal to 0.
Douglas Crockford makes a lot of recommendations, but you don't have to take them as gospel. :)
T.J. Crowder makes an excellent suggestion of studying the ECMAScript Language Specification to know the whole story behind these equality tests.
Further Reading?
The spec.
yolpo (on falsy values)
Best Answer
The equality operator will attempt to make the data types the same before making the comparison. On the other hand, the identity operator requires both data types to be the same as a prerequisite.
There are quite a few other posts out there similar to this questions. See:
How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ? (has a nice comparison chart)
Which equals operator (== vs ===) should be used in JavaScript comparisons?
In practice, the identity operator comes in really handy when you want to be certain that a boolean value is true or false since...