I think forEach is incorrectly categorized as a mutator function, since it does not modify the array itself, it only might modify the state of the objects inside the array. Actually, most of the non-mutator functions can also modify the state of the objects, for example map and filter.
Nice overview. But yes, I would not say .forEach() mutates too, since it is just kind of loop function - passed function may or may not mutate array on which it runs, it could be used for some side effects, it could be used to modify totally different array/object - it is just a loop over items in array and it does not imply any kind of function / computation in that loop.
ForEach itself does not mutate the array. But the function passed as parameter can mutate the array. And mostly forEach is used with a function parameter therefore it's more a mutator than a non-mutator. For the others, map and filter they both return a new array and reduce return a single value. But overall they does not mutate the original array.
You pass a function to map and filter as well, so they are also able to change the state of the object. Obviously, it's a bad practice to do so but still possible.
You have to reassign e.g. arr = arr.map(x=>x**x), since arr.map(x=>x*x) won't change arr itself, it is new array, same as .filter.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.