By the end of this lesson, you will be able to use JavaScript bitwise operators to manipulate integer values at the binary level, including AND, OR, XOR, NOT, shifts, and zero-fill right shift.
What it is
Bitwise operators work on the binary representation of numbers. In JavaScript, most bitwise operators first convert operands to 32-bit signed integers, perform the operation, and return a normal Number. Think of each bit as a tiny switch: 0 means off, 1 means on. Related terms include bit, mask, sign bit, two's complement, and shift.
Why it matters
- Combine and test permission flags compactly, such as read, write, and execute.
- Extract or pack small fields inside one integer, such as RGB color channels.
- Perform fast integer operations like multiplying or dividing by powers of two.
- Build low-level algorithms for hashing, checksums, and bitboards.
- Understand JavaScript's 32-bit integer boundary when working with large numbers.
Syntax or steps
The smallest useful patterns are:
value & maskkeeps only the bits present in both.value | maskturns on bits from the mask.value ^ masktoggles bits from the mask.value & ~maskturns off bits from the mask.value << nshifts bits left bynpositions.value >> nshifts bits right while preserving the sign.value >>> nshifts bits right and fills with zeros.
Use parentheses when mixing bitwise operators with comparisons, because bitwise operators have lower precedence than equality operators.
Example
const READ = 1;
const WRITE = 2;
const EXECUTE = 4;
let permissions = READ | WRITE; // 3
console.log(permissions & EXECUTE); // 0
console.log((permissions & WRITE) === WRITE); // true
permissions ^= EXECUTE; // toggle execute -> 7
console.log(permissions); // 7
const color = 0xff8800;
const red = (color >> 16) & 0xff;
const green = (color >> 8) & 0xff;
const blue = color & 0xff;
console.log(red, green, blue); // 255 136 0
console.log(5 & 3); // 1
console.log(5 | 3); // 7
console.log(5 ^ 3); // 6
console.log(~5); // -6
console.log(5 << 2); // 20
console.log(20 >> 2); // 5
console.log(-1 >>> 0); // 4294967295
READ | WRITE sets the first two bits. permissions & EXECUTE tests whether the execute bit is set. permissions ^= EXECUTE toggles it. The color example shifts the packed value right, then masks with 0xff to keep one byte. 5 & 3 returns 1 because 101 and 011 share only the lowest bit. ~5 returns -6 because JavaScript treats the flipped 32-bit pattern as a signed integer.
Common mistakes
- Assuming bitwise operators work on
BigIntandNumbertogether. Mixing them throws aTypeError; useBigIntoperators for large integers. - Forgetting the 32-bit limit. Values larger than 32 bits may be truncated before the operation.
- Using
>>when you need an unsigned result. For example,-1 >> 1stays negative, while-1 >>> 1becomes a large positive number. - Writing
x & 1 === 0without parentheses. It is parsed asx & (1 === 0), so use(x & 1) === 0.
When to use it
Use bitwise operators when you need compact integer flags or packed data. Use logical operators for boolean conditions, arithmetic for ordinary math, and BigInt for integers beyond 32 bits.
| Goal | Use | Example |
|---|---|---|
| Combine boolean conditions | Logical operators | a && b |
| Set or test flags | Bitwise operators | flags | READ |
| Large integer bit work | BigInt | 1n << 64n |
| Normal multiplication | Arithmetic | x * 4 |
Practice
Guided exercise: create a flag value, set bit 2, then test whether bit 2 is on.
let flags = 0;
flags |= 1 << 2;
console.log(flags); // 4
console.log((flags & (1 << 2)) !== 0); // true
Challenge: extract the lowest 4 bits of 0x3f and clear them from 0x3f. Hint: use mask = 0b1111, then low = value & mask and cleared = value & ~mask.
Quick check
What does 12 & 10 return?
Answer: 8, because 1100 & 1010 is 1000.
Summary
Bitwise operators let you treat integers as collections of binary switches. They are powerful for flags, masks, and packed data, but they operate on 32-bit integer conversions. Choose them for low-level integer work, and choose logical, arithmetic, or BigInt tools when those fit the problem better.