JavaScript Operators
Operators are symbols in JavaScript that perform specific mathematical, logical, or assignment operations. Understanding the usage and precedence of various operators is crucial for writing correct JavaScript code. In this chapter, we will learn in depth about various operators and their usage in JavaScript.
What are Operators
Operators are symbols used to perform specific operations. They can operate on one or more operands. Operands can be variables, constants, or expressions.
let x = 5 + 3; // + is the operator, 5 and 3 are operands
let y = x * 2; // * is the operator, x and 2 are operandsClassification of Operators
Operators in JavaScript can be classified according to different criteria:
By Number of Operands
- Unary operators: Require only one operand
- Binary operators: Require two operands
- Ternary operator: Requires three operands
By Function
- Arithmetic operators
- Assignment operators
- Comparison operators
- Logical operators
- Bitwise operators
- String operators
- Conditional (ternary) operator
- Comma operator
- Unary operators
- Relational operators
Arithmetic Operators
Arithmetic operators are used to perform basic mathematical operations.
let a = 10;
let b = 3;
// Addition
console.log(a + b); // 13
// Subtraction
console.log(a - b); // 7
// Multiplication
console.log(a * b); // 30
// Division
console.log(a / b); // 3.3333333333333335
// Modulo (remainder)
console.log(a % b); // 1
// Exponentiation (ES2016)
console.log(a ** b); // 1000 (10 to the power of 3)
// Increment
let c = 5;
console.log(++c); // 6 (prefix increment)
console.log(c++); // 6 (postfix increment)
console.log(c); // 7
// Decrement
let d = 5;
console.log(--d); // 4 (prefix decrement)
console.log(d--); // 4 (postfix decrement)
console.log(d); // 3
// Unary plus (convert to number)
console.log(+"5"); // 5
console.log(+"hello"); // NaN
// Unary minus (convert to negative)
console.log(-"5"); // -5
console.log(-"hello"); // NaNAssignment Operators
Assignment operators are used to assign values to variables.
let x = 10;
// Basic assignment
x = 5; // x = 5
// Addition assignment
x += 3; // x = x + 3 = 8
// Subtraction assignment
x -= 2; // x = x - 2 = 6
// Multiplication assignment
x *= 4; // x = x * 4 = 24
// Division assignment
x /= 3; // x = x / 3 = 8
// Modulo assignment
x %= 5; // x = x % 5 = 3
// Exponentiation assignment (ES2016)
x **= 2; // x = x ** 2 = 9
// Left shift assignment
x <<= 1; // x = x << 1 = 18
// Right shift assignment
x >>= 1; // x = x >> 1 = 9
// Unsigned right shift assignment
x >>>= 1; // x = x >>> 1 = 4
// Bitwise AND assignment
x &= 3; // x = x & 3 = 0
// Bitwise XOR assignment
x ^= 5; // x = x ^ 5 = 5
// Bitwise OR assignment
x |= 2; // x = x | 2 = 7
// Logical AND assignment (ES2020)
let obj = {};
obj &&= "has value"; // obj = obj && "has value" = "has value"
// Logical OR assignment (ES2020)
let value = null;
value ||= "default"; // value = value || "default" = "default"
// Nullish coalescing assignment (ES2020)
let data = null;
data ??= "default data"; // data = data ?? "default data" = "default data"Comparison Operators
Comparison operators are used to compare two values and return a boolean value (true or false).
let a = 5;
let b = "5";
let c = 10;
// Equality
console.log(a == b); // true (equal after type conversion)
console.log(a === b); // false (strict equality, no type conversion)
// Inequality
console.log(a != b); // false (equal after type conversion)
console.log(a !== b); // true (strict inequality)
// Greater than
console.log(c > a); // true
// Less than
console.log(a < c); // true
// Greater than or equal
console.log(c >= a); // true
// Less than or equal
console.log(a <= c); // true
// Special comparison cases
console.log(null == undefined); // true
console.log(null === undefined); // false
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // trueLogical Operators
Logical operators are used to combine multiple boolean expressions.
let x = true;
let y = false;
let a = 5;
let b = 0;
// Logical AND (&&)
console.log(x && y); // false
console.log(a && b); // 0 (short-circuit evaluation)
console.log(a && "hello"); // "hello"
// Logical OR (||)
console.log(x || y); // true
console.log(b || a); // 5 (short-circuit evaluation)
console.log(b || "default"); // "default"
// Logical NOT (!)
console.log(!x); // false
console.log(!b); // true
console.log(!!a); // true (double negation converts to boolean)
// Nullish coalescing operator (??) - ES2020
console.log(null ?? "default"); // "default"
console.log(undefined ?? "default"); // "default"
console.log("" ?? "default"); // ""
console.log(0 ?? "default"); // 0
// Logical nullish assignment (??=) - ES2020
let config = { theme: null };
config.theme ??= "light";
console.log(config.theme); // "light"Bitwise Operators
Bitwise operators operate on the binary representation of numbers.
let a = 5; // Binary: 101
let b = 3; // Binary: 011
// Bitwise AND (&)
console.log(a & b); // 1 (Binary: 001)
// Bitwise OR (|)
console.log(a | b); // 7 (Binary: 111)
// Bitwise XOR (^)
console.log(a ^ b); // 6 (Binary: 110)
// Bitwise NOT (~)
console.log(~a); // -6 (Binary: ...11111010)
// Left shift (<<)
console.log(a << 1); // 10 (Binary: 1010)
// Right shift (>>)
console.log(a >> 1); // 2 (Binary: 10)
// Unsigned right shift (>>>)
console.log(a >>> 1); // 2 (same as >> for positive numbers)String Operators
The main string operator in JavaScript is the concatenation operator.
// String concatenation
let firstName = "John";
let lastName = "Doe";
let fullName = firstName + " " + lastName; // "John Doe"
// String and number concatenation
let age = 25;
let message = "I am " + age + " years old"; // "I am 25 years old"
// Compound assignment concatenation
let greeting = "Hello";
greeting += ", World!"; // "Hello, World!"
// Template strings (ES6)
let name = "Jane";
let template = `Hello, ${name}!`; // "Hello, Jane!"Conditional (Ternary) Operator
The ternary operator is a shorthand form of the if...else statement.
let age = 18;
// Basic usage
let status = age >= 18 ? "Adult" : "Minor";
console.log(status); // "Adult"
// Nested ternary operator
let score = 85;
let grade = score >= 90 ? "Excellent" :
score >= 80 ? "Good" :
score >= 70 ? "Average" :
score >= 60 ? "Pass" : "Fail";
console.log(grade); // "Good"
// Used in function calls
function getDiscount(isMember) {
return isMember ? 0.1 : 0;
}
let discount = getDiscount(true); // 0.1
// Used in object properties
let user = {
name: "John",
role: "admin",
permissions: user.role === "admin" ? ["read", "write", "delete"] : ["read"]
};Comma Operator
The comma operator allows multiple expressions to be executed in a single statement.
// Basic usage
let a = (1, 2, 3); // a = 3 (returns the value of the last expression)
// Used in for loops
for (let i = 0, j = 10; i < 5; i++, j--) {
console.log(`i: ${i}, j: ${j}`);
}
// Complex expression
let x = (console.log("First expression"),
console.log("Second expression"),
"Final value");
console.log(x); // "Final value"Unary Operators
Unary operators require only one operand.
let a = 5;
// delete operator
let obj = { name: "John", age: 25 };
delete obj.age;
console.log(obj); // { name: "John" }
// typeof operator
console.log(typeof a); // "number"
console.log(typeof "hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (JavaScript historical issue)
// void operator
let result = void 0; // undefined
console.log(result); // undefined
// in operator
let person = { name: "John", age: 25 };
console.log("name" in person); // true
console.log("salary" in person); // false
// instanceof operator
let arr = [1, 2, 3];
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // trueOperator Precedence
Operator precedence determines the order in which operators are executed in an expression.
// Precedence example
let result1 = 3 + 4 * 5; // 23 (multiplication has higher precedence)
let result2 = (3 + 4) * 5; // 35 (parentheses have highest precedence)
// Same precedence operators (left to right)
let result3 = 10 - 5 - 2; // 3 (calculated left to right)
// Assignment operators (right to left)
let a, b, c;
a = b = c = 5; // a = b = c = 5
// Short-circuit evaluation of logical operators
let x = null;
let y = x && x.length; // null (won't execute x.length)
let z = x || "default"; // "default"Operator Associativity
When operators have the same precedence, associativity determines the order of operations.
// Left associativity
let result1 = 10 - 5 - 2; // (10 - 5) - 2 = 3
// Right associativity
let a, b, c;
a = b = c = 5; // a = (b = (c = 5))
// Right associativity of ternary operator
let grade = score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" : "D";Type Conversion and Operators
Operators often involve type conversion.
// Implicit type conversion
console.log("5" + 3); // "53" (string concatenation)
console.log("5" - 3); // 2 (numeric operation)
console.log(true + 1); // 2 (true converts to 1)
console.log(false + 1); // 1 (false converts to 0)
console.log("5" * "3"); // 15 (strings convert to numbers)
// Explicit type conversion
console.log(Number("5") + 3); // 8
console.log(String(5) + 3); // "53"
console.log(Boolean(0)); // false
// Type conversion in comparison operators
console.log(0 == ""); // true
console.log(0 == "0"); // true
console.log(false == "0"); // true
console.log(null == undefined); // trueBest Practices for Operators
1. Use Strict Equality Operators
// Recommended: use strict equality
if (value === null) {
// Handle null
}
if (value === undefined) {
// Handle undefined
}
// Not recommended: use loose equality
// if (value == null) {
// // Matches both null and undefined
// }2. Use Short-Circuit Evaluation Wisely
// Safe access to object properties
let user = getUser();
let name = user && user.profile && user.profile.name;
// Using optional chaining (ES2020)
let name2 = user?.profile?.name;
// Default value setting
let config = getConfig() || defaultConfig;
// Using nullish coalescing operator (ES2020)
let config2 = getConfig() ?? defaultConfig;3. Be Aware of Operator Precedence
// Use parentheses to clarify intent
let result1 = (a + b) * c; // Clear
let result2 = a + b * c; // Can be confusing
// Use parentheses for complex expressions
let isValid = (user.age >= 18) && (user.isActive || user.isAdmin);4. Avoid Overusing Ternary Operators
// Use ternary operator for simple cases
let status = age >= 18 ? "Adult" : "Minor";
// Use if...else for complex cases
if (score >= 90) {
grade = "A";
} else if (score >= 80) {
grade = "B";
} else if (score >= 70) {
grade = "C";
} else {
grade = "D";
}
// Instead of:
// let grade = score >= 90 ? "A" :
// score >= 80 ? "B" :
// score >= 70 ? "C" : "D";Practical Examples
1. Math Calculation Utility
class Calculator {
// Safe division
static divide(a, b) {
if (b === 0) {
throw new Error("Cannot divide by zero");
}
return a / b;
}
// Percentage calculation
static percentage(value, total) {
return total !== 0 ? (value / total) * 100 : 0;
}
// Range check
static inRange(value, min, max) {
return value >= min && value <= max;
}
// Number formatting
static formatNumber(num, decimals = 2) {
return Number(num.toFixed(decimals));
}
// Safe number conversion
static toNumber(value, defaultValue = 0) {
const num = Number(value);
return isNaN(num) ? defaultValue : num;
}
}
// Usage examples
console.log(Calculator.divide(10, 2)); // 5
console.log(Calculator.percentage(25, 100)); // 25
console.log(Calculator.inRange(5, 1, 10)); // true
console.log(Calculator.formatNumber(3.14159, 2)); // 3.14
console.log(Calculator.toNumber("123.45")); // 123.452. String Processing Utility
class StringOperations {
// Safe string concatenation
static concat(...strings) {
return strings.filter(str => str != null).join("");
}
// String repetition
static repeat(str, times) {
return str.repeat(Math.max(0, times || 0));
}
// String padding
static pad(str, length, char = " ", position = "left") {
str = String(str);
if (str.length >= length) return str;
const padLength = length - str.length;
const padding = char.repeat(Math.ceil(padLength / char.length)).substring(0, padLength);
return position === "left" ? padding + str : str + padding;
}
// String truncation
static truncate(str, length, suffix = "...") {
str = String(str);
if (str.length <= length) return str;
return str.substring(0, length - suffix.length) + suffix;
}
// Word count
static wordCount(str) {
return str.trim().split(/\s+/).filter(word => word.length > 0).length;
}
}
// Usage examples
console.log(StringOperations.concat("Hello", " ", "World")); // "Hello World"
console.log(StringOperations.repeat("*", 5)); // "*****"
console.log(StringOperations.pad("5", 3, "0")); // "005"
console.log(StringOperations.truncate("This is a very long string", 15)); // "This is a ve..."
console.log(StringOperations.wordCount("Hello world JavaScript")); // 33. Logic Operations Utility
class LogicOperations {
// Safe logical AND
static and(...values) {
for (let value of values) {
if (!value) return value;
}
return values[values.length - 1];
}
// Safe logical OR
static or(...values) {
for (let value of values) {
if (value) return value;
}
return values[values.length - 1];
}
// Conditional selection
static select(condition, trueValue, falseValue) {
return condition ? trueValue : falseValue;
}
// Multi-condition check
static all(...conditions) {
return conditions.every(condition => condition);
}
static any(...conditions) {
return conditions.some(condition => condition);
}
// Negate condition
static not(condition) {
return !condition;
}
}
// Usage examples
console.log(LogicOperations.and(true, true, false)); // false
console.log(LogicOperations.or(false, false, true)); // true
console.log(LogicOperations.select(5 > 3, "greater", "less")); // "greater"
console.log(LogicOperations.all(5 > 3, 10 > 5, "hello")); // true
console.log(LogicOperations.any(5 > 10, 10 > 5, "")); // trueOperator Precedence Table
Here is the precedence of JavaScript operators (from highest to lowest):
- Grouping:
() - Member access:
. [] - new (with argument list):
new - Function call:
() - Optional chaining:
?. - new (without argument list):
new - Postfix increment/decrement:
++ -- - Prefix increment/decrement:
++ -- - Unary plus/minus:
+ - - Bitwise NOT:
~ - Logical NOT:
! - typeof:
typeof - void:
void - delete:
delete - Exponentiation:
** - Multiplication/Division/Modulo:
* / % - Addition/Subtraction:
+ - - Bitwise shift:
<< >> >>> - Relational operators:
< <= > >= in instanceof - Equality operators:
== != === !== - Bitwise AND:
& - Bitwise XOR:
^ - Bitwise OR:
| - Logical AND:
&& - Logical OR:
|| - Nullish coalescing:
?? - Conditional operator:
?: - Assignment operators:
= += -= *= /= %= **= <<= >>= &= ^= |= ??= &&= ||= - Comma operator:
,
Summary
Key points about JavaScript operators:
- Arithmetic operators: +, -, *, /, %, **, ++, --
- Assignment operators: =, +=, -=, *=, /=, %=, **=, etc.
- Comparison operators: ==, ===, !=, !==, >, <, >=, <=
- Logical operators: &&, ||, !, ??, &&=, ||=, ??=
- Bitwise operators: &, |, ^, ~, <<, >>, >>>
- String operators: +, += (concatenation)
- Conditional operator: ? : (ternary operator)
- Unary operators: delete, typeof, void, in, instanceof
- Comma operator: ,
- Operator precedence: Determines expression evaluation order
- Type conversion: Implicit and explicit conversions involving operators
- Best practices: Use strict equality, use short-circuit evaluation wisely, be aware of precedence
Mastering operators is the foundation for writing efficient, correct JavaScript code. In the next chapter, we will learn about JavaScript regular expressions.