- == (Double equals operator): Known as the equality or abstract comparison operator
- === (Triple equals operator): Known as the identity or strict comparison operator
In this post, we’ll explore the similarities and differences between these operators.
Let’s declare two variables
bar and compare them using both operators.
var foo = 13; var bar = 13; console.log(foo == bar); // true console.log(foo === bar); // also true
In the above example, both operators returned the same answer i.e.
true. So what’s the difference?
The Difference between
The difference between
=== is that:
==converts the variable values to the same type before performing comparison. This is called type coercion.
===does not do any type conversion (coercion) and returns true only if both values and types are identical for the two variables being compared.
Let’s take a look at another example:
var one = 1; var one_again = 1; var one_string = "1"; // note: this is string console.log(one == one_again); // true console.log(one === one_again); // true console.log(one == one_string); // true. See below for explanation. console.log(one === one_string); // false. See below for explanation.
- Line 7:
console.log(one == one_string)returns true because both variables,
one_stringcontain the same value even though they have different types:
oneis of type
String. But since the
==operator does type coercion, the result is true.
- Line 8:
console.log(one === one_string)returns false because the types of variables are different.
=== Faster than
==? A Quick Look at the Performance of the Two Operators
In theory, when comparing variables with identical types, the performance should be similar across both operators because they use the same algorithm. When the types are different, triple equals operator (
===) should perform better than double equals (
==) because it doesn’t have to do the extra step of type coercion. But does it? Here are some performance tests you could try yourself to see for yourself.
If you look at the graph at the bottom of the tests, you’d see performance varies across different browser implementations and the gains in performance are almost negligible.
But if you think about it, performance is totally irrelevant and shouldn’t play a role in deciding when to use one operator over the other. Either you need type coercion or you don’t. If you don’t need it, don’t use double equals operator (
==) because you might get unexpected results. Most linters will complain if you use
==. To further scare you away from
==: it’s pretty confusing and has odd rules. For example,
"1" == true or
"" == 0 will return
In short, always use
=== everywhere except when you need type coercion (in that case, use
=== have their counterparts when it comes to checking for inequality:
!=: Converts values if variables are different types before checking for inequality
!==: Checks both type and value for the two variables being compared
var one = 1; var one_again = 1; var one_string = "1"; // note: this is a string console.log(one != one_again); // false console.log(one != one_string); // false console.log(one !== one_string);// true. Types are different
Equality Operators and Objects (and other reference types)
So far, we have been exploring equality or inequality operators using primitive types. What about reference types like Arrays or Objects. If we create two arrays that have identical contents, can we compare them using equalty operators the same way we do it for primitives? The answer is no, you can’t. Let’s take a look at an example:
var a1 = [1,2,3,4,5] var a2 = [1,2,3,4,5] console.log(a1 == a2); // false console.log(a1 === a2); // false
Here, both the
=== return the same answer:
false. What’s happening here is that both
a2 are pointing to different objects in memory. Even though the array contents are the same, these essentially have different values. Same applies to objects and other reference types.
ECMAScript 6: Object.is()
Triple equals operator (
===) is the recommended way for value comparison, but it’s not perfect. Here’s couple of examples where its behavior is confusing:
console.log(+0 === -0); // true console.log(NaN === NaN); // false
To make comparisons less confusing, ECMAScript 6 introduced a new method: Object.is(). It takes two arguments and returns
true if both the values and types are equal. Essentially, its identical to the
=== operator, but without its quirks. Let’s take a look at some examples:
console.log(Object.is(2, 2)); // true console.log(Object.is(2, "2")); // false. Different types // And it fixes the quirks of === console.log(Object.is(+0, -0)); // false console.log(Object.is(NaN, NaN));// true
I wouldn’t say that
is confusing (as humans, at least). The first is pretty obvious, as +0 and -0 represent the same quantity, semantically. The second actually makes sense if you understand that equality is a property between two numbers. Since NaN is not a number, it makes sense it’s not equal to itself. This actually lends to pretty neat NaN checking for a given value, as such:
Of course this is all preference, but it’s not entirely unintuitive. Great article though :)
Very good article, thanks!
Allow me just one comment: that NaN===NaN returns false is not a quirk, but it’s like that in every decent floating point implementation (i.e. following IEEE 745), and makes perfect sense in a mathematical way. NaN’s are the result of undefined mathematical operations like Infinity-Infinity or Infinity*0 and it just makes no sense to declare the results of two undefined operation to be the same.
Very consistent & helpful article. Thank you.
very clearly explained
Eric M Hill
Brilliant. This may be the best article I’ve yet encountered on Google Apps Script. Thank you! Oh, and you convinced me to make the switch to ===. I’m new to Apps Script and JS, and was a bit frustrated by the extremely loose == equality operator, but === will directly address my concerns. Thanks again!