DevelopmentJavaScript | 6 Min Read
JavaScript Array Methods: Array.prototype.every() Explained
The Array is one of the most important data types in JavaScript, here is everything you need to know about the Array method Array.prototype.every().
Series Introduction
The JavaScript Array data type currently has 37 methods on it according to the MDN docs and in this series we are going to cover them all one by one explaining each with examples as we work our way down the list.
If you have any questions regarding anything in this series please get in contact with me by using the methods listed at the bottom of this post and if you think I've got something wrong please create a pull request on GitHub to correct the information (link at the bottom of the article).
This is post #7 in the series. If you're interested in reading any of the other posts in this series, there is a up-to-date list at the bottom of this post.
Method #7: Array.prototype.every()
Have you ever wanted to find out if every value in an array passes a set criteria, yes? Then .every() is the method for you.
The .every() method allows you to test if every value in a given array passes a set criteria by calling a callback function on each value. If all the values within the array return a truthy value then the overall method returns True, if one of the passed values fails the callback function and returns a falsy value then the overall method returns False.
Syntax
Let's have a more in depth look at the syntax of this method to see what is required and how to use it.
1arr.every( callback( element [, index [, array ] ] ) [, thisArg ] )
jsxParameters
The .every() method takes in 2 top level parameters:
- Callback function: This is where you define yours tests to compare the iterated value. This callback function takes in 3 arguments:
- Element: The current element being processed from the passed array
- Index: The index of the current element being processed in the array.
- Array: The original array the .every() method was called upon.
- thisArg: A value to be used as the .this value when executing the callback function, if omitted a value of undefined will be used.
Return
There is only two possible return values for the .every() method:
- True: If all of the tested values in the array return a truthy value then True is returned overall.
- False: If any of the tested values fail the passed callback function then the method exits and returns a value of False.
If the .every() method is called upon an empty array then the returned value will always be True regardless of the callback function.
Other Info
- The callback function will only be invoked for array indexes with assigned values, if the index does not have a value assigned or has been deleted then the callback will not be invoked.
- The .every() method will not mutate the original array it has been called upon.
- The elements that .every() will process is decided before the first invocation of the callback function, this means if you add or remove any values to the original array they will not be processed by the callback function. However, if a value is changed during the execution of the method then the changed value is passed to the callback function when that index is visited.
Examples
Below are some examples to cover the various aspects of the .every() method:
Testing if array values are >= X
1[5, 10, 15, 20, 25].every(function (num, index) {2 return num >= 5;3});4// True
jsxUsing arrow functions
1[5, 10, 15, 20, 25].every((num, index) => num >= 5); // True
jsxRemoving items during the callback
1const arr = [1, 2, 3, 4];2arr.every((num, index, arr) => {3 arr.pop();4 console.log(`[${arr}][${index}] -> ${num}`);5 // [1,2,3][0] -> 16 // [1,2][1] -> 27 return num < 4;8}); // True
jsxThe above code will only loop over the array twice as the remaining items are removed using .pop(), this means that the code will return True.
This happens because when all of the values in the array are compared to the condition they are less than 4 meaning they return True on the condition, therefore the entire method returns True.
The only value that would have returned False is the last value in the array but as this was .pop()'d' off when we invoked the callback function with the first value, there are no values left that would fail the conditional when compared.
Adding items during the callback
1const arr1 = [1, 2, 3];2arr1.every((num, index, arr) => {3 arr1.push("num");4 console.log(`[${arr}][${index}] => ${num}`);5 console.log(arr.length);6 return arr.length > 3;7}); // True
jsxThe above code demonstrates an important point we need to remember when adding items using the .every() method, even if we add new items to the array during the callback, the new items are not passed into the original array that the .every() method was called on so they will not have the callback function invoked on them, this is why the above code will only log out:
1// [1,2,3,num][0] => 12// [1,2,3,num,num][1] => 23// [1,2,3,num,num,num][2] => 3
jsxEven though we have added items to the array they are not logged out as an element accessed on the original array. This happens because only items inside the array when .every() was called have the callback function invoked on them, this is shown by the indexes we accessed ( 0 - 2 ).
We need to remember to take this into account when writing our conditionals inside the callback function or we could end up short-circuiting the callback and getting the wrong boolean returned.
In the example of the code above, normally the conditional would return False on the initial array as it's not greater than 3 but as we add a new item to the array before running the conditional it passes and returns a value of True. If this was unintended it could cause possible issues with our code and should be considered.
Modifying items during the callback
1const arr = [1, 2, 3, 4];2arr.every((elem, index, arr) => {3 arr[index + 1] -= 1;4 console.log(`[${arr}][${index}] -> ${elem}`);5 return elem < 2;6}); // False
jsxWithout us modifying the array in the callback function of the above code, it would normally only run for 2 iterations before returning False.
1// [1,2,3,4][0] -> 12// [1,2,3,4][1] -> 1
jsxHowever, with us modifying the array, the callback function is invoked three times before returning False:
1// [1,1,3,4][0] -> 12// [1,1,2,4][1] -> 13// [1,1,2,3][2] -> 2
jsxThis shows how modifying the array can alter the returned values of the callback function and should be considered when writing any callback functions that modify the original array.
Examples taken from / inspired by the MDN Docs
Summing Up.
.every() can be a powerful method for comparing a series of values but if we are using it to modify, add, or delete values then we need to ensure we fully evaluate the possible changes and implications that could occur to our values and how that will impact the final boolean returned.
I hope you enjoyed this post and if you have any questions regarding this method or any of the other methods in this series, you can contact me via the links below where I would be happy to answer them for you.
See you in the next post. 😃
Series links
- #1: Array.from()
- #2: Array.isArray()
- #3: Array.of()
- #4: Array.prototype.concat()
- #5: Array.prototype.copyWithin()
- #6: Array.prototype.entries()
- #7: Array.prototype.every()