JAVASCRIPT / ARRAYS
every, some, and testing whole arrays
Use every and some to collapse an array into one true/false answer, predict where each short-circuits, and reason correctly about empty and sparse arrays.
What you will learn
- Choose every or some by phrasing the question as 'all of them' or 'at least one'
- Predict how many callback calls run before every or some short-circuits
- Explain why [].every(p) is true and [].some(p) is false, and guard against it
- Rewrite !arr.every(p) as arr.some(x => !p(x)) when it reads better
Understanding every, some, and testing whole arrays
every and some run a predicate over the elements and collapse the whole array into a single boolean: every asks whether the predicate holds for all of them, some asks whether it holds for at least one. The predicate is called with (value, index, array), and its result is judged by truthiness, so returning 0, an empty string, or undefined counts as a failure exactly like false. Neither method hands back an element, which is the job of find and findIndex, and neither changes the array it walks.
The mental model is a loop carrying a verdict that quits the moment the verdict can no longer change. every starts out believing the answer is true and returns false at the first falsy result; some starts out believing false and returns true at the first truthy one. This short-circuit is guaranteed by the language rather than an optimization you might or might not get, so elements after the deciding one are genuinely never passed to your callback.
Because the two are mirror images, the empty array falls out of the definitions instead of being a special case: [].every(p) is true because there is no counterexample, and [].some(p) is false because there is no witness. That is why every on its own is a weak validation gate, since a cart or form with no entries passes any check you can write. The same symmetry gives a rewrite rule: !arr.every(p) asks exactly the same question as arr.some(x => !p(x)), so pick whichever phrasing reads more plainly at the call site.
const temps = [21, 19, 24, 30, 18];
console.log('all above 15:', temps.every(t => t > 15));
console.log('all above 20:', temps.every(t => t > 20));
console.log('any above 28:', temps.some(t => t > 28));
console.log('any above 40:', temps.some(t => t > 40));
// 'not all at most 28' is the same question as 'some above 28'
console.log('not all at most 28:', !temps.every(t => t <= 28));
const noReadings = [];
console.log('empty every:', noReadings.every(t => t > 100));
console.log('empty some:', noReadings.some(t => t > 100));every and some are bounded quantifiers over an array: they return a boolean as soon as one element settles 'for all' or 'there exists', which is also why an empty array answers true and false respectively.
Worked examples
Where the scan actually stops
Counters prove that every and some abandon the array as soon as one element decides the answer.
const nums = [2, 4, 5, 6, 8, 10];
let everyCalls = 0;
let someCalls = 0;
const allEven = nums.every(n => { everyCalls++; return n % 2 === 0; });
const anyOdd = nums.some(n => { someCalls++; return n % 2 !== 0; });
console.log(allEven, 'decided after', everyCalls, 'calls');
console.log(anyOdd, 'decided after', someCalls, 'calls');
console.log('but the array holds', nums.length, 'numbers');Example explained
Line 1every stopped at 5, the first odd number, because one failure already settles the 'all even' question.
Line 2some stopped at the same element, because 5 is the first witness for 'at least one odd'.
Line 3Both counters read 3 for a six-element array, so 6, 8 and 10 were never passed to either callback.
Line 4The variables hold plain booleans, not the number 5 that decided them.
Using the index parameter
A sortedness test built from every by comparing each element with its predecessor.
const isSorted = list => list.every((value, i, arr) => i === 0 || arr[i - 1] <= value);
console.log(isSorted([1, 3, 3, 9]));
console.log(isSorted([1, 3, 2, 9]));
console.log(isSorted([42]));
console.log(isSorted([]));Example explained
Line 1The second and third parameters are the index and the array itself, which is what makes a neighbour comparison possible inside every.
Line 2The i === 0 branch is required: arr[-1] is undefined, and undefined <= 1 evaluates to false, which would fail every array.
Line 3[1, 3, 2, 9] returns false at index 2, so the pair (2, 9) is never compared.
Line 4A single-element array and an empty array are both reported as sorted, which matches the mathematical definition rather than being a bug.
Truthiness, not booleans
How non-boolean predicate results and array holes change the answer.
const words = ['', 'hi', 'there'];
console.log(words.some(w => w.length));
console.log(words.every(w => w.length));
console.log(words.every(w => w.trim));
console.log([0, null, ''].some(Boolean));
console.log(new Array(3).every(w => w === 7));Example explained
Line 1some is true because 'hi' returns 2 and any non-zero number is truthy; the empty string's 0 is treated as a plain failure.
Line 2The same predicate makes every false, since the length 0 of '' is coerced to false and rejects the array.
Line 3every(w => w.trim) returns a method, and functions are always truthy, so this test passes for anything and checks nothing.
Line 4new Array(3) is three holes with no elements to visit, so every returns true without calling the callback once.
Important notes
Both methods skip holes but do visit explicit undefined: [ , , ].every(v => v === 1) is true, while [undefined, undefined].every(v => v === 1) is false.
The predicate's result is coerced by truthiness, but every and some themselves always return exactly true or false, never the element that decided the outcome.
Common mistakes
Writing arr.every(n => { n > 0 }) with braces and no return: the callback yields undefined, which is falsy, so every reports false for any non-empty array and the check rejects valid data.
Using every as a validation gate without checking length: an empty cart, empty form, or empty upload list passes every rule you wrote, because there is no element left to fail one.
Counting or logging inside the predicate: short-circuiting stops the callback as soon as the answer is known, so the tally is silently short for exactly the arrays that fail.
Try it yourself
Change, predict, then run
In the browser console build const cart = [{qty: 2}, {qty: 0}, {qty: 5}], then write one every expression reporting whether every line has a positive qty and one some expression reporting whether any line is empty. Set cart.length = 0, run both again, and explain why the two answers now agree that nothing is wrong.
Open the JavaScript workspaceCheck your understanding
A checkout page decides an order is valid with items.every(i => i.qty > 0). Why can an invalid order still slip through?
- Because every stops at the first item and never inspects the rest of the list
- Because every skips items whose qty is 0, the same way it skips holes in a sparse array
- Because every returns true for an empty array, so an order with no line items is judged valid
- Because every returns the first item that passes rather than a boolean, and objects are always truthy
Show answer
every is a 'for all' test, and an empty array offers no counterexample, so zero line items passes the guard and the page needs a separate items.length check. The short-circuit option describes real behaviour but is harmless: every only stops early when an item fails the predicate, which is precisely when it should return false.