7 Comparison and Logical Operators
7.1 Comparison Operators
JavaScript’s comparison operators evaluate expressions and return boolean values (true
or false
). They’re essential for creating conditions in if
statements, loops, and anywhere you need to make decisions in your code.
Operator | Name | Description | Example | Result |
---|---|---|---|---|
== |
Equality | Compares values, performs type coercion | 5 == "5" |
true |
=== |
Strict equality | Compares values and types, no coercion | 5 === "5" |
false |
!= |
Inequality | Compares if values are not equal, with coercion | 5 != "6" |
true |
!== |
Strict inequality | Compares if values or types are different | 5 !== "5" |
true |
> |
Greater than | Checks if left value is greater than right | 5 > 3 |
true |
< |
Less than | Checks if left value is less than right | 5 < 3 |
false |
>= |
Greater than or equal | Checks if left is greater than or equal to right | 5 >= 5 |
true |
<= |
Less than or equal | Checks if left is less than or equal to right | 5 <= 5 |
true |
7.1.1 Type Coercion in Comparisons
The non-strict operators (==
, !=
) perform type coercion, which can sometimes lead to unexpected results:
0 == false // true (false coerced to 0)
0 === false // false (different types)
"" == false // true (both coerced to 0)
"" === false // false (different types)
null == undefined // true (special case in JavaScript)
null === undefined // false (different types)
7.1.2 Important Coercion Rules:
- When comparing a string with a number, JavaScript converts the string to a number
- When comparing a boolean with anything, JavaScript converts the boolean to a number (false → 0, true → 1)
- When comparing an object with a primitive, JavaScript attempts to convert the object to a primitive
7.1.3 Best Practice:
Almost all modern JavaScript style guides recommend using the strict equality operators (===
and !==
) by default to avoid unexpected behavior from type coercion. Only use loose equality (==
and !=
) when you specifically want type coercion to occur.
7.2 Logical Operators
Logical operators are used to combine or modify boolean expressions.
Operator | Name | Description | Example | Result |
---|---|---|---|---|
&& |
Logical AND | Returns true if both operands are true | true && true |
true |
\|\| |
Logical OR | Returns true if either operand is true | false \|\| true |
true |
! |
Logical NOT | Returns the opposite boolean value | !true |
false |
?? |
Nullish coalescing | Returns right operand if left is null/undefined | null ?? "default" |
"default" |
7.2.1 Short-Circuit Evaluation
JavaScript’s logical operators use “short-circuit” evaluation, which means they stop evaluating as soon as the result is determined:
// AND operator - stops at first false value
false && anyExpression // Returns false without evaluating anyExpression
true && false // Evaluates both sides, returns false
// OR operator - stops at first true value
true || anyExpression // Returns true without evaluating anyExpression
false || true // Evaluates both sides, returns true
7.2.2 Return Values (Not Just Booleans!)
A key point about JavaScript’s logical operators is that they don’t always return boolean values. They return the value of the operand that determined the result:
// AND returns the first falsy value, or the last value if all are truthy
"Hello" && 0 && true // Returns 0 (first falsy value)
"Hello" && 42 && true // Returns true (last value, all are truthy)
// OR returns the first truthy value, or the last value if all are falsy
"" || 0 || "Hello" // Returns "Hello" (first truthy value)
"" || 0 || false // Returns false (last value, all are falsy)
This behavior enables a common pattern for setting default values:
function greet(name) {
= name || "Guest"; // If name is falsy, use "Guest" instead
name return "Hello, " + name;
}
// Modern approach using nullish coalescing
function greetBetter(name) {
= name ?? "Guest"; // Only uses "Guest" if name is null or undefined
name return "Hello, " + name;
}
7.2.3 Nullish Coalescing Operator (??
)
The nullish coalescing operator (??
) is a newer addition to JavaScript (ES2020). It works like the OR operator, but only considers null
and undefined
as triggering the right-hand side:
0 || "default" // Returns "default" (0 is falsy)
0 ?? "default" // Returns 0 (0 is not null or undefined)
"" || "default" // Returns "default" (empty string is falsy)
"" ?? "default" // Returns "" (empty string is not null or undefined)
null ?? "default" // Returns "default"
undefined ?? "default" // Returns "default"
This is particularly useful when you want to provide a default value only when a variable is null or undefined, but want to keep other falsy values like 0 or empty strings.
7.2.4 Logical Assignment Operators
ES2021 introduced logical assignment operators that combine logical operations with assignment:
Operator | Description | Equivalent to |
---|---|---|
&&= |
Logical AND assignment | x = x && y |
\|\|= |
Logical OR assignment | x = x \|\| y |
??= |
Nullish coalescing assignment | x = x ?? y |
Examples:
let a = true;
&&= false; // Same as: a = a && false (results in false)
a
let b = false;
||= true; // Same as: b = b || true (results in true)
b
let c = null;
??= "default"; // Same as: c = c ?? "default" (results in "default") c
7.3 Comparison and Logical Operators in Practice
Here’s a practical example combining comparison and logical operators in a real-world scenario:
function validateUserInput(username, age, email) {
// Check if username is provided and at least 3 characters
const isUsernameValid = username && username.length >= 3;
// Check if age is a number and at least 18
const isAgeValid = typeof age === 'number' && age >= 18;
// Simple email validation (contains @ and .)
const isEmailValid = email && email.includes('@') && email.includes('.');
// User is valid if all validations pass
const isUserValid = isUsernameValid && isAgeValid && isEmailValid;
// Provide feedback on what's invalid
if (!isUserValid) {
return {
valid: false,
errors: {
username: !isUsernameValid ? "Username must be at least 3 characters" : null,
age: !isAgeValid ? "Age must be at least 18" : null,
email: !isEmailValid ? "Please provide a valid email" : null
};
}
}
return { valid: true };
}
// Example usage
const result = validateUserInput("Jo", 17, "invalid-email");
console.log(result);
// {
// valid: false,
// errors: {
// username: "Username must be at least 3 characters",
// age: "Age must be at least 18",
// email: "Please provide a valid email"
// }
// }
7.4 Comparison with R and Python
Coming from R and Python, these are key differences to be aware of:
- JavaScript has both strict (
===
) and loose (==
) equality operators, unlike Python’s single==
- JavaScript’s logical operators (
&&
,||
) return the determining value, not justtrue
orfalse
- JavaScript’s type coercion rules are more complex than Python’s
- R’s vectorized operations don’t exist in JavaScript (operations apply to single values, not to entire arrays automatically)
Understanding these comparison and logical operators is fundamental to controlling the flow of your JavaScript programs and writing robust conditions for your applications.