== vs === in JavaScript: What’s the Difference? (with Examples)

Double equals and triple equals operators in JavaScript

In JavaScript, the difference between the == operator and === operator is in how the comparison is made:

  • The == operator checks if the two values are equal without caring about their data type.
  • The === operator checks if the two values are equal given they have the same data type.

A great way to see this is by comparing a number and a string that represents the same number:

console.log("1" == 1)  // true
console.log("1" === 1) // false
  • The first comparison yields true because the == operator converts the string “1” to a number and compares it with the number 1.
  • The second comparison returns false because you try to compare a string with a number, which makes no sense.

As it turns out, the == operator converts the comparables to a common type before making a comparison.

A fancy word for this conversion is implicit type coercion.

Before digging into the details of == and === in JavaScript, let’s briefly discuss implicit type coercion.

In this guide, you learn:

  • What is the type coercion (implicit and explicit)
  • What is the difference between == and === operators
  • How == and === comparison operators work with
    • primitive types (strings, numbers, booleans)
    • reference types (arrays and other collections)

Type Coercion in JavaScript

In JavaScript, type coercion refers to changing the type of data.

For instance, converting a string to a number is type coercion.

In JavaScript, type coercion can only be used to turn values into:

  • String
  • Number
  • Boolean

You cannot coerce an object to any other type, such as to function or object.

In JavaScript, type coercion can be of type:

  • Implicit type coercion
  • Explicit type coercion

Let’s take a moment to understand what these mean.

Explicit Type Coercion

Explicit type coercion, as the name suggests, means doing type coercion explicitly.

In layman’s terms, this means manually converting the type of a value.

Usually, this means using a built-in function, such as String(), Number(), or Boolean().

For instance, let’s convert a string to a number and add another number to it

const numstr = "100"

// Convert the string to number (explicit type coercion)
const num = Number(numstr)

console.log(num + 10)

Output:

110

If you did not convert the string to a number, you would not be able to sum it up with another number.

Now, let’s talk about implicit type coercion, that is, the type coercion that automatically takes place under the hood.

Implicit Type Coercion

In JavaScript, implicit type coercion means that a value is converted from one data type to another automatically.

The word implicit refers to it happening under the hood.

Implicit type coercion only takes place if you try to perform an operation on two operands of different types.

For instance, if you compare two values of a different type, implicit type coercion converts the values to Number type. Then it compares the numeric values.

Here are some examples

"1" == 1        // 1 == 1       --> true
true == "true"  // true == NaN  --> false
"0" == false    // 0 == 0       --> true

You now understand how implicit type coercion works in JavaScript.

This also gave you a glimpse of how the == operator compares values in JavaScript.

Next, let’s talk about the == operator.

Loose Equality Operator (==)

In JavaScript, the loose equal operator (==) loosely compares two values.

If you compare two values of different data types, the == operator implicitly coerces both values to numbers.

A loose equality operator thus can return true even if the types of the compared values do not match.

For instance:

"1" == 1        // true
true == "true"  // false
"0" == false    // true

But this can sometimes be problematic.

Instead of loosely comparing values, you should be able to perform a more strict comparison that ensures values are of the same type before the comparison.

This is where the strict equality operator (===) comes in.

Strict Equality Operator (===)

The strict equality operator (===) does not implicitly coerce the values being compared.

In layman’s terms, it does not convert the compared elements to the same data type.

Thus, if the compared values represent different data types, the strict comparison automatically returns false.

So a string cannot be strictly equal to a number, for example.

Here are some examples:

"1" === 1        // false
true === "true"  // false
"0" === false    // false

2 === 2          // true
"A" === "A"      // true

Let’s get to the interesting part: What is the difference between == and === in JavaScript?

== vs === in JavaScript

With everything you have learned so far, understanding what is the difference between == and === becomes trivial.

  • The loose equality operator == uses implicit type coercion to convert the comparables to a common type if needed.
  • The strict equality operator === does directly compares the values and does not convert them to a common data type.

Thus, if you try to compare values of different type, the == operator can return true, but the === operator cannot.

To this point you have seen examples with numbers, strings, and booleans.

These data types belong to a group called primitive types in JavaScript.

However, there is an entirely different group of data types in JavaScript called reference types (or objects), such as arrays.

Comparing reference types with == and === operators has a different meaning which is important to understand.

Comparing Reference Types vs Primitive Types

In JavaScript, data types are either primitive types or reference types.

Examples of primitive types are numbers, strings, and booleans.

Examples of reference types are arrays, functions, and other collections.

Let’s take a look at how the comparison operators work with both primitive types and reference types in more detail.

Primitive Types

The primitive types of JavaScript are:

  • Boolean
  • Number
  • String
  • Symbol
  • Undefined
  • Null
  • BigInt

All the primitive types define immutable values.

In other words, you cannot directly change the values of primitive types. Instead, you need to create a new primitive type.

Let’s demonstrate the immutability with a simple example:

let a = 1
a = 2

In this piece of code, you actually do not directly change the number object from 1 to 2.

Instead, you create an entirely new Number object and make the variable a reference to it.

Assigning a new value makes a variable point to another address in memory
The original number remains untouched. Instead, a new number is created and assigned.

Comparisons with Primitive Types

Now, let’s get back to the comparison operators == and ===.

As you learned, there is a difference between == and === operators when it comes to comparing primitive types:

  • The == operator loosely compares the values by converting them to a common type.
  • The === operator does not convert the compared objects. Instead, it checks if both the compared values are of the same type and their value is equal.

When it comes to comparing reference-type objects, the comparison operators have an entirely different meaning.

Although, the difference between the == and === operators remains.

Reference Types

In JavaScript, objects are mutable collections of properties that do not have a fixed size.

A JavaScript object is also called a reference type.

A reference type means the objects are passed by reference in code.

Examples of reference types are arrays, functions, and other types of collections.

To demonstrate reference types, let’s create an array, copy it to a new variable, and change the original array:

let a = [1, 2, 3]
let b = a

a[0] = 1000

console.log(a) // [ 1000, 2, 3 ]
console.log(b) // [ 1000, 2, 3 ]

As you can see, changing the first element in the original array a also affects the “copied” array b.

This is because let b = a does not actually create a copy of the array. Instead, it creates a new reference to the original array.

Two variables pointing in the same memory address

This same logic applies to all other JavaScript objects that store collections of properties.

Comparisons with Reference Types

With reference types, the comparison operators (== and ===) check if two objects reference the same object.

In other words, you can use the comparison operators to check if the two objects point to the same address in memory.

Let me show you a demonstrative example.

let a = [1, 2, 3]
let b = [1, 2, 3]
let c = a

console.log(a === b) // false
console.log(a === c) // true

As you can see:

  • a === b returns false. This is because a and b are different objects in memory even though they look identical.
  • a === c returns true. This is because a and c point to the same object in memory.

Here is a behind-the-scenes illustration of the above:

Arrays a and b point to different variables. C points to the same as a.

The arrays a and c reference the same chunk of memory. This happens because of this line of code:

let c = a

As you learned, instead of copying, this piece of code creates a new reference called c that points to the original array a.

This is really important to understand, yet it is not talked about often.

For instance, this explains why you cannot check if two arrays have equal elements using the == or === operators. To do this, you need to loop through the array element by element.

The difference between the == operator and === operator in reference types is the same as in primitive types:

  • The == operator converts the compared items to a common data type. If you try to compare a reference type to a primitive type, the type coercion tries to convert the reference to a primitive type.
  • The === operator does not use type coercion at all. If the two compared values are both not reference types, it automatically returns false.

Now you not only understand what is the difference between == and ===, but you also know how comparison operators work differently in different contexts.

Last but not least, let’s answer the question of which comparison operator you should use.

Which Comparison Operator Should I Use: == or ===?

The short answer: Always use the triple equals operator === to make comparisons in JavaScript.

The == operator tries to do type coercion, which can result in strange behavior in your code.

Here are some examples of some comparisons with == that produce unexpected results:

false == 0             // true
false == ""            // true
0 == ""                // true
undefined == null      // true
[] == false            // true
[] == 0                // true

But when compared with === all these comparisons produce a reasonable and predictable result:

false === 0             // false
false === ""            // false
0 === ""                // false
undefined === null      // false
[] === false            // false
[] === 0                // false

To be on the safe side, use the === operator for making comparisons.

Conclusion

Today you learned what is the difference between the == and === operators in JavaScript.

To recap:

To understand how the == operator works, you need to understand what is implicit type coercion.

Implicit type coercion means the JavaScript parser automatically converts two values to a common type in order to perform an operation on them.

For example, to add a string to a number, the number needs to be converted to a string or the string to a number.

With this information, you can easily understand what is the difference between the == and === operators in JavaScript:

  • The == operator converts the two comparables to a common type before comparison. This way for example a string can be equal to a number.
  • The === operator does not do the type coercion. It checks if both the value and the type of the comparables are equal to one another.

Also, it is important to understand that the comparison operators == and === work entirely differently with reference types, such as arrays.

Instead of comparing if the elements are equal to one another, the operators check if the two objects reference the same object in memory.

Try to use the === operator as much as possible. This way you can avoid the “anomalies” related to using the == operator.

Scroll to Top