Bitwise operators in JavaScript often go unnoticed by many developers—especially beginners or those who rarely dive into low-level logic. However, understanding these operators can open up powerful techniques in performance optimization, cryptography, graphics programming, flag manipulation, and more.
In this comprehensive guide, we’ll demystify the topic: JavaScript Bitwise Operators Explained. You’ll learn how they work, where they’re used, and why they’re still relevant in modern JavaScript development.
JavaScript Prototypes: How Inheritance Works
What Are Bitwise Operators?
Bitwise operators operate directly on the binary representation of numbers. That is, they manipulate bits—the 1s and 0s that form the actual underlying data.
JavaScript represents numbers as 64-bit floating point values, but bitwise operations treat them as 32-bit signed integers.
In simpler terms:
- Decimal numbers are converted to 32-bit integers.
- Operations are performed on these integers at the bit level.
- The result is then converted back into a JavaScript number.
List of Bitwise Operators in JavaScript
Here are the standard bitwise operators:
Operator | Symbol | Name |
---|---|---|
AND | & | Bitwise AND |
OR | ` | ` |
XOR | ^ | Bitwise XOR |
NOT | ~ | Bitwise NOT |
Left Shift | << | Shifts bits to the left |
Sign-propagating Right Shift | >> | Shifts bits to the right, preserving the sign |
Zero-fill Right Shift | >>> | Shifts bits right, filling with zeros |
Each of these plays a unique role, which we’ll explore in detail next.
Understanding Binary Representation
Before we dive into operations, you should know how numbers look in binary.
Example:
let num = 5;
// Binary: 00000000000000000000000000000101 (32-bit)
This binary system forms the foundation of all bitwise operations.
Bitwise AND (&
)
Usage: Compares two bits and returns 1 only if both are 1.
Bit A | Bit B | A & B |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
console.log(5 & 3); // 1
Why?
- 5 in binary:
0101
- 3 in binary:
0011
- Result:
0001
→ 1
Use Case: Often used in flags and permissions to check if a bit is set.
Bitwise OR (|
)
Usage: Compares bits and returns 1 if at least one is 1.
Bit A | Bit B | A | B |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
console.log(5 | 3); // 7
- 5 in binary:
0101
- 3 in binary:
0011
- Result:
0111
→ 7
Use Case: Used to set specific bits (e.g., enabling permissions).
Bitwise XOR (^
)
Usage: Returns 1 if the bits are different.
Bit A | Bit B | A ^ B |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
console.log(5 ^ 3); // 6
- 5 →
0101
- 3 →
0011
- Result →
0110
→ 6
Use Case: Swapping values without temporary variables.
let a = 10, b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
// a is now 20, b is now 10
Bitwise NOT (~
)
Usage: Inverts the bits (1s become 0s and vice versa).
console.log(~5); // -6
Why?
- 5 →
00000000000000000000000000000101
- ~5 →
11111111111111111111111111111010
→ -6 (two’s complement)
Use Case: Used for inverting bit flags or implementing simple math tricks.
Left Shift (<<
)
Usage: Shifts all bits to the left by a specified number of places, filling with zeros from the right.
console.log(5 << 1); // 10
- 5 →
0101
- Shift left →
1010
→ 10
Shifting left by 1 is equivalent to multiplying by 2.
5 << 3 // 5 * 2^3 = 40
Use Case: Bit-level multiplication optimization.
Sign-Preserving Right Shift (>>
)
Usage: Shifts bits to the right, preserving the sign (copies leftmost bit).
console.log(-10 >> 1); // -5
console.log(10 >> 1); // 5
Use Case: Division by powers of 2 for signed numbers.
Zero-Fill Right Shift (>>>
)
Usage: Shifts bits to the right, filling with zeros regardless of sign.
console.log(-10 >>> 1); // 2147483643
Why the large number?
Because it forces the number to become unsigned during the shift.
Use Case: Handling unsigned integers or manipulating raw binary data.
Bitwise Operators with Boolean Logic
Bitwise operators work on numbers, not boolean values. But since true
becomes 1
and false
becomes 0
, you can use bitwise logic on boolean results:
console.log(true & false); // 0
console.log(true | false); // 1
Still, this is generally discouraged in favor of regular logical operators (&&
, ||
) unless performance is critical.
Practical Applications of Bitwise Operators
Now that we understand how bitwise operators work, let’s explore where they’re useful in real projects.
1. Managing Flags (Permissions & Status)
const READ = 1; // 0001
const WRITE = 2; // 0010
const EXECUTE = 4; // 0100
let permission = READ | WRITE; // 0011
// Check if WRITE is allowed
if (permission & WRITE) {
console.log("Can write!");
}
Efficient way to store multiple boolean states in one number.
2. Image Processing & Graphics
Graphics engines use bitwise operations to manipulate pixel values, alpha channels, and colors at lightning speed.
3. Performance Optimization
Bitwise operations are faster than arithmetic in low-level operations like:
let x = x * 2; // slower
let x = x << 1; // faster
However, for modern JavaScript engines, the difference is often negligible.
4. Masking Values
const byte = 0b10101101;
const mask = 0b00001111;
const lower4 = byte & mask;
console.log(lower4.toString(2)); // 1101
Used to isolate specific bits in a binary pattern.
5. Cryptography and Security Algorithms
Hash functions and encryption algorithms often use XOR operations and bit shifts to scramble data securely.
Common Mistakes When Using Bitwise Operators
1. Using Them on Non-Integers
JavaScript auto-converts values to 32-bit integers. If you’re working with large floating-point numbers, precision may be lost.
2. Using ~
for Logical Negation
Don’t confuse ~
(bitwise NOT) with !
(logical NOT):
~0 === -1 // Not the same as !0
3. Thinking They Work on Booleans
Even though truthy/falsy values can be coerced to numbers, always be clear about intent to avoid bugs.
Should You Use Bitwise Operators in Everyday JavaScript?
Short answer: It depends.
✅ Use them when:
- You need performance optimization.
- You’re dealing with binary protocols or graphics.
- You’re building flag systems or permission controls.
❌ Avoid when:
- Readability matters more than performance.
- Team members are unfamiliar with bit-level logic.
Conclusion: Bitwise Logic Is Still Relevant
While bitwise operators might seem obscure or “too low-level” for typical web development tasks, they remain a core part of the JavaScript language—and for good reason. They offer performance benefits, compact code, and unique functionality not achievable with higher-level operations.
Here’s a final summary of what we covered:
- Bitwise operators manipulate 32-bit integers at the bit level.
- Operations include AND, OR, XOR, NOT, and various shifts.
- They have practical uses in permissions, flags, cryptography, and more.
- Understanding how they work can deepen your mastery of JavaScript.
Whether you’re building a game engine, optimizing performance, or just want to sharpen your coding skills, mastering bitwise operators will give you an edge.
If you’d like this content optimized for SEO or exported to Markdown/PDF for a blog or portfolio, just let me know!