avatarDr. Derek Austin 🥳

Summary

This context explains the difference between double equals (==) and triple equals (===) in JavaScript, focusing on type coercion and strict equality.

Abstract

The context starts by introducing the concept of double equals (==) and triple equals (===) in JavaScript, explaining that double equals tests for standard equality and triple equals tests for strict equality. The author emphasizes that the key to understanding this difference lies in learning about type coercion in JavaScript, a dynamically typed language. Type coercion occurs because JavaScript tries to be resilient against programming errors, such as comparing a number and a string.

The author then goes on to explain the concept of truthy and falsy values in JavaScript. There are six falsy values: false, 0 (zero), "", null, undefined, and NaN (Not A Number). Everything else is considered truthy. The author also provides examples and explanations of how truthy and falsy values work in JavaScript.

Finally, the author delves into the technical details of how the strict equality operators and standard equality operators work in JavaScript, providing the exact algorithms used by the language.

Bullet points

  • Double equals (==) test for standard equality and triple equals (===) test for strict equality in JavaScript.
  • Type coercion is an essential concept in understanding the difference between double equals and triple equals in JavaScript.
  • Type coercion occurs because JavaScript tries to be resilient against programming errors, such as comparing a number and a string.
  • JavaScript has six falsy values: false, 0 (zero), "", null, undefined, and NaN (Not A Number).
  • Everything else in JavaScript is considered truthy.
  • The strict equality operators and standard equality operators use different algorithms in JavaScript.
  • The author provides examples and explanations of how truthy and falsy values work in JavaScript.

Making Sense of == vs. === in JavaScript

Double equals (==) test standard equality and triple equals (===) test strict equality

Photo by Charles "Duck" Unitas on Unsplash

Equal should be equal, right? JavaScript’s triple equals comparison always used to confuse me. Most languages have == but not ===.

Here’s the difference between double and triple equals in JavaScript:

“Use [===] strict equality operators if the operands must be of a specific type as well as value or if the exact type of the operands is important.

Otherwise, use [==] the standard equality operators, which allow you to compare the identity of two operands even if they are not of the same type.” —MDN web docs

The key for my understanding was to learn about “type coercion” — an odd concept in Vanilla JavaScript, which is a dynamically typed language.

Type coercion occurs because JavaScript tries to be resilient against programming errors, such as comparing a number and a string.

Brandon Morelli explains type coercion like this, on codeburst.io:

“When using double equals in JavaScript we are testing for loose equality. Double equals also perform type coercion.

Type coercion means that two values are compared only after attempting to convert them into a common type.”

In other words, the values would get compared with == because of the type coercion, but strings will never equal numbers with ===.

For example:

The Meaning of Truth: Falsy and Truthy in JavaScript

In JavaScript, there are six falsy values: false, 0(zero), "" (empty string), null, undefined, and NaN(Not A Number).

Brandon Morelli explains how falsy values work:

“Comparing false, 0, and "" with loose equality (==) will result in equality. null and undefined are only equal to themselves. NaN isn’t equivalent to anything (not even itself!).” — JavaScript Showdown: == vs. ===

Fortunately, everything else is truthy, according to the MDN web docs:

“In JavaScript, a truthy value is a value that is considered true when encountered in a Boolean context. All values are truthy unless they are defined as falsy (i.e., except for false, 0, "", null, undefined, and NaN).

A Peek Under the Hood: How It Really Works in ECMAScript

For those curious, here are the exact algorithms used by JavaScript:

Strict equality operators

The strict equality operators (=== and !==) use the Strict Equality Comparison Algorithm to compare two operands:

11.9.6 The Strict Equality Comparison Algorithm

The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:

1. If Type(x) is different from Type(y), return false.

2. If Type(x) is Undefined, return true.

3. If Type(x) is Null, return true.

4. If Type(x) is Number, then

→ a. If x is NaN, return false.

→ b. If y is NaN, return false.

→ c. If x is the same Number value as y, return true.

→ d. If x is +0 and y is −0, return true.

→ e. If x is −0 and y is +0, return true.

→ f. Return false.

5. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.

6. If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.

7. Return true if x and y refer to the same object. Otherwise, return false.

NOTE — This algorithm differs from the SameValue Algorithm (9.12) in its treatment of signed zeroes and NaNs.

Standard equality operators

The standard equality operators (== and !=) use the Abstract Equality Comparison Algorithm to compare two operands:

11.9.3 The Abstract Equality Comparison Algorithm

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

1. If Type(x) is the same as Type(y), then

→ a. If Type(x) is Undefined, return true.

→ b. If Type(x) is Null, return true.

→ c. If Type(x) is Number, then

→ → i. If x is NaN, return false.

→ → ii. If y is NaN, return false.

→ → iii. If x is the same Number value as y, return true.

→ → iv. If x is +0 and y is −0, return true.

→ → v. If x is −0 and y is +0, return true.

→ → vi. Return false.

→ d. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.

→ e. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.

→ f. Return true if x and y refer to the same object. Otherwise, return false.

2. If x is null and y is undefined, return true.

3. If x is undefined and y is null, return true.

4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).

5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

8. If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).

9. If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.

10. Return false.

NOTE 1 — Given the above definition of equality:

• String comparison can be forced by: "" + a == "" + b.

• Numeric comparison can be forced by: +a == +b.

• Boolean comparison can be forced by: !a == !b.

NOTE 2 — The equality operators maintain the following invariants:

A != B is equivalent to !(A == B).

A == B is equivalent to B == A, except in the order of evaluation of A and B.

NOTE 3 The equality operator is not always transitive. For example, there might be two distinct String objects, each representing the same String value; each String object would be considered equal to the String value by the == operator, but the two String objects would not be equal to each other. For example:

new String("a") == "a" and "a" == new String("a")are both true.

new String("a") == new String("a") is false.

NOTE 4 Comparison of Strings uses a simple equality test on sequences of code unit values. There is no attempt to use the more complex, semantically oriented definitions of character or string equality and collating order defined in the Unicode specification. Therefore Strings values that are canonically equal according to the Unicode standard could test as unequal. In effect this algorithm assumes that both Strings are already in normalized form.

Conclusion

Generally, I prefer === and !==, except when I have a good reason to use == or !=, such as in the case of null checks.

When checking for null, knowing that null and undefined are equal with == can be useful.

Additional Reading

  • According to Basarat Ali Syed’s excellent free book TypeScript Deep Dive, ==and === work the same in both JavaScript and TypeScript:

Dr. Derek Austin is the author of Career Programming: How You Can Become a Successful 6-Figure Programmer in 6 Months, now available on Amazon.

JavaScript
Programming
Software Development
Web Development
Coding
Recommended from ReadMedium