JavaScript equality ==
, also called loose or abstract equality, returns a boolean after checking whether two operands are equal.
<operand A> == <operand B>
// OR
<operand B> == <operand A>
You can negate its output by replacing the first equality sign with an exclamation mark.
<operand A> != <operand B>
The difference between JavaScript equality and strict equality ===
is that it attempts to convert operands into one type (type coercion) before comparing them, whereas strict equality does not.
So, what is the impact of using JavaScript equalilt? Is strict equality better than loose equality? Find out below.
Understand key data types
JavaScript has seven primary data types: string, number, boolean, null, undefined, symbol, and object.
Strings
A string is an array of characters.
const str = "JavaScript equals can be challenging."
console.log(typeof str)
The str
variable packs multiple characters. We use the typeof
operator to check its data type.
Numbers
The number data type represents whole numbers and decimals.
const myIntNumber = 15
const myDoubleDiscount = 15.93
console.log(typeof myIntNumber)
console.log(typeof myDoubleDiscount)
An object is a key-value paired data type. The most familiar objects are literals and arrays.
const literal = {a: 3, b: 7}
const array = ["string", 19, true]
console.log(typeof literal, typeof array)
A boolean tells whether a condition is true or false. true
denotes something exists, while false
represents non-existence. Boolean logic is crucial in determining truthiness and falsiness.
Primitives vs Objects
Data types that are not objects are called primitives, whereas objects are reference data types.
You can use a constructor function to create a variable. The resulting variable is an object. Otherwise, it is literal. Almost all data types are a descendant of a constructor function.
Here are some examples.
const stringLiteral = "I like to compare strings."
const stringObject = new String("I like to compare strings.")
const numberLiteral = 89
const numberObject = new Number(89)
console.log(typeof stringLiteral) // string
console.log(typeof stringObject) // object
console.log(typeof numberLiteral) // number
console.log(typeof numberObject) // object
Likewise, we can check the resulting data type or boolean representative of a variable.
const booleanLiteral = false
const booleanObject = new Boolean(null)
console.log(typeof booleanLiteral) // boolean
console.log(typeof booleanObject) // object
new String()
, new Number()
, and new Boolean()
are built-in constructors. We can also create a custom constructor function.
function Person (name) {
this.name = name
}
const personLiteral = "John Doe"
const personObject = new Person( "John Doe")
console.log(typeof personLiteral) // string
console.log(typeof personObject) // object
It would be best to understand how JavaScript equals attempts to convert operands before deciding to settle for loose or strict equality.
How JavaScript equality compares operands
Here are some of the ways JavaScript equality converts or translates operands.
Same data types
String (Rule~1): returns true if the operands have the same characters in the same order.
console.log("doe" == "doe") // true
console.log("doe" == "Doe") // false
"doe" == "doe"
equates to true because both strings are doe
in lowercase. On the other hand, "doe" == "Doe"
result in false because doe
's characters are all in lowercase while Doe
's first character is uppercase.
Number (Rule~2): returns true if the operands have the same value.
console.log(3 == 3) // true
console.log(3 == 13) // false
boolean (Rule~3): returns true if both operands are true or false.
console.log(false == false) // true
console.log(true == false) // false
symbol (Rule~4): returns true if both operands refer to the same symbol.
Different data types
String vs number (Rule~5): JavaScript equality converts a string to a number before comparing a string operand to a number operand.
console.log(17 == "17") // true
console.log(17 == "37") // false
Strings ("17" and "37") were converted to numbers: 17 and 37, respectively. 17 == 17
results to true because the comparison obeys Rule~2, while 17 == 37
does not.
object vs primitive (Rule~6): JavaScript equality converts the object to a primitive before comparing the operands.
const numObject = new Number(97)
const numPrimitive = 97
console.log(numObject == numPrimitive) // true
The object was converted to a number before the comparison: 97 == 97
.
Booleans vs other data types (Rule~7): If one of the operands is a boolean, it converts it to a number (true => 1, false => 0) before comparing the operands.
console.log(true == 1) // true
console.log(0 == false) // true
console.log(true == 19) // false
true
converts to 1 before comparing it to 1 and 19, respectively. 1 == 1
results in true, while 1 == 19
is false. Likewise, JavaScript equality converts false to 0 before comparing it to 0. According to Rule~2, 0 == 0
returns true.
null
or undefined
vs other data types (Rule~8): If you compare null
or undefined
with another data type, JavaScript equality returns true only if the other operand has been converted to null
or undefined
.
Symbols vs other data types (Rule~9): JavaScript equality returns false
if one operand is a symbol while the other is not.
Conclusion
The key takeaway from this tutorial is that JavaScript equality complicates comparing operands. It could result in lengthy debugging sessions or unreliable applications. Where possible, use strict equality ===
instead of loose equality ==
.
Further Reading
Equality (==) - JavaScript - MDN Web Docs
Equality comparisons and sameness - JavaScript | MDN