How to check if a number is even in JavaScript
Checking if a number is even is fundamental for alternating patterns, conditional logic, zebra-striping tables, pagination, and data grouping in JavaScript applications. With over 25 years of experience in software development and as the creator of CoreUI, I’ve used even/odd checks extensively in table row styling, layout systems, and component logic. For the companion check, see how to check if a number is odd in JavaScript.
Use the modulo operator % to test if a number is divisible by 2.
4 % 2 === 0 // true — even
7 % 2 === 0 // false — odd
-4 % 2 === 0 // true — negative even numbers work correctly
0 % 2 === 0 // true — zero is even by definition
1. Basic Even Check
The modulo operator returns the remainder after division. An even number divided by 2 has remainder 0.
const isEven = n => n % 2 === 0
isEven(0) // true
isEven(2) // true
isEven(7) // false
isEven(-4) // true
isEven(-3) // false
A reusable arrow function is the most common pattern. Use it anywhere you need a boolean.
2. Bitwise Approach (Performance-Critical Code)
For tight loops processing large datasets, a bitwise AND check is faster than modulo because it operates directly on the binary representation. An even number always has its least significant bit set to 0.
const isEvenBitwise = n => (n & 1) === 0
isEvenBitwise(4) // true — binary 100, last bit 0
isEvenBitwise(5) // false — binary 101, last bit 1
isEvenBitwise(-4) // true — two's complement, last bit still 0
In practice, the difference is negligible for typical UI workloads. Prefer % 2 === 0 for readability unless you have profiling evidence that the bitwise version matters.
3. Filtering Even Numbers from an Array
A common use case is extracting only even values from a dataset.
const numbers = [1, 2, 3, 4, 5, 6, 7, 8]
const evens = numbers.filter(n => n % 2 === 0)
// [2, 4, 6, 8]
const evenIndices = numbers.filter((_, i) => i % 2 === 0)
// [1, 3, 5, 7] — elements at even indices (0, 2, 4, 6)
Note the difference: filtering by value vs filtering by index position. Both patterns appear frequently in list rendering and data processing.
4. Zebra-Striping Table Rows
Even/odd index checks are the standard way to apply alternating row styles in dynamically rendered tables.
const rows = ['Alice', 'Bob', 'Carol', 'Dave']
rows.forEach((name, index) => {
const row = document.createElement('tr')
row.className = index % 2 === 0 ? 'row-even' : 'row-odd'
row.textContent = name
table.appendChild(row)
})
In CSS:
.row-even { background-color: #f8f9fa; }
.row-odd { background-color: #ffffff; }
CoreUI’s CTable component provides a striped prop that handles this automatically — use it when working within a CoreUI project.
5. Pagination — Detecting Even Page Numbers
Even/odd page detection is useful for two-sided print layouts or alternating sidebar positions.
function getPageLayout(pageNumber) {
return pageNumber % 2 === 0 ? 'left-page' : 'right-page'
}
getPageLayout(1) // 'right-page'
getPageLayout(2) // 'left-page'
getPageLayout(10) // 'left-page'
6. Handling Floating-Point Inputs
The modulo check works mathematically for floats but may produce surprising results due to IEEE 754 precision. Guard with an integer check when the input may not be a whole number.
2.0 % 2 === 0 // true — fine
2.5 % 2 === 0 // false — not even (expected)
2.0000000001 % 2 === 0 // false — precision issue
function isEvenSafe(n) {
if (!Number.isInteger(n)) return false
return n % 2 === 0
}
isEvenSafe(4) // true
isEvenSafe(4.0) // true — 4.0 is an integer in JS
isEvenSafe(4.5) // false — correctly rejects float
Best Practice Note:
Use n % 2 === 0 as your default — it is readable, correct for all integers including negatives and zero, and fast enough for virtually any use case.
Reach for the bitwise (n & 1) === 0 only when profiling shows a genuine bottleneck.
Always pair the even check with an integer guard (Number.isInteger) when the input comes from user input or an external API.



