Validating a form before it is sent, holding an order back while one line is out of stock, allowing a post once every required field is filled: the question asked is always the same one, do all the items follow the rule.
every answers it with true or false, with no counter and no flag to keep track of.
Definition
every is an Array method that calls a function on each item and hands back true only if that function answered true everywhere. A single item that fails is enough to get false.
const fields = [
{ name: "email", filled: true },
{ name: "password", filled: true },
{ name: "terms", filled: false },
];
console.log(fields.every((f) => f.filled)); // false
console.log(fields.some((f) => f.filled)); // true
const languages = ["fr", "en", "es"];
console.log(languages.every((l) => l.length === 2)); // trueWhat comes back is always a boolean, never the offending item. It therefore drops straight into an if, and that is what sets every apart from Array.find(), which hands back the item itself.
Stopping at the first failure
The function is not called on every item: as soon as one answer is false, the walk stops, since the verdict can no longer change.
let calls = 0;
const allPositive = [1, 2, -3, 4, 5].every((n) => {
calls += 1;
return n > 0;
});
console.log(allPositive); // false
console.log(calls); // 3, the values 4 and 5 were never examinedTwo practical consequences. Putting the test most likely to fail first speeds up the answer on large arrays. And above all, the function must produce no Side effect: counting, logging or incrementing inside an every gives a result that depends on where the walk happened to stop.
The empty-array case
every hands back true on an empty array. That is not a flaw: no rule was broken, since no item was examined. The surprise shows up in production.
console.log([].every((n) => n > 100)); // true
console.log([].some((n) => n > 100)); // false
const cart = [];
const orderable = cart.every((line) => line.stock > 0);
console.log(orderable); // true, while there is nothing to orderThe guard is one extra condition: cart.length > 0 && cart.every(...). Write it as soon as the list can arrive empty, which covers almost any data coming out of a database.
Frequently asked questions
How does it differ from Array.some()?
Both hand back a boolean, but they do not ask the same question. every asks whether all of them pass, Array.some() whether at least one passes. The first stops at the first failure, the second at the first success. On an empty array, the first answers true and the second false.
Can an every be interrupted halfway?
It already interrupts itself at the first failure, and break has no effect inside a function. If you need to know which item failed the test, Array.find() hands back that item and findIndex hands back its position.
How do you check that two arrays hold the same values?
By comparing the lengths first, then each position: a.length === b.length && a.every((v, i) => v === b[i]). The second argument the function receives is the index, which is what makes the comparison possible. This only holds for simple values: two objects with identical content stay different under Strict equality (===).