How do I loathe thee? Let me count the ways… The method has been around awhile. Like , and , it operates upon an array of values by invoking a callback function. Array.reduce() map() filter() find() Here’s an example from the : developer.mozilla.org site const array1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue; // 1 + 2 + 3 + 4 console.log(array1.reduce(reducer)); // expected output: 10 // 5 + 1 + 2 + 3 + 4 console.log(array1.reduce(reducer, 5)); // expected output: 15 Seems straightforward, right? On with the grievances: 0. It doesn’t do what you expect Let’s look at this again: const array1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue; // expected: 1 + 2 + 3 + 4 === 10 Now I’ll modify the reducer function to add 1 to each value of the array, then sum it with the previous value. Since I’m adding 1 to four array elements, I expect to get a sum of 14. const array1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue + 1; // (1+1) + (2+1) + (3+1) + (4+1) = 2+3+4+5 = 14 console.log(array1.reduce(reducer)); // unexpected output: 13 Hold on… what? Turns out the first element of the array is the initial accumulator value. So, instead of (1+1) + (2+1) + (3+1) + (4+1) = 2+3+4+5 = 14 It is actually: 1 + (2+1) + (3+1) + (4+1) = 2+3+4+5 = 13 All that use a function as can you. You can get to the right answer, of course: just add an accumulator initial value as a second argument to the reduce method: those reduce examples online sum illustration mislead console.log(array1.reduce(reducer, 0)); // desired output: 14 1. It’s misnamed The name would lead one to believe that it reduces an array of element to a subset of those elements. That’s not really what it does. It can do the opposite of reduce, in fact: reduce const array1 = [1, 2, 3, 4]; // four elements const increaser = (accumulator, currentValue) => { accumulator.push(currentValue); accumulator.push(currentValue*currentValue); return accumulator; }; console.log(array1.reduce(increaser, [])); // output: Array [1, 1, 2, 4, 3, 9, 4, 16] (8 elements) And it doesn’t even have to return an array: const array1 = [1, 2, 3, 4]; const transformer = (accumulator, currentValue) => { accumulator[currentValue] = currentValue*currentValue; return accumulator; }; console.log(array1.reduce(transformer, {})); // output: Object { 1: 1, 2: 4, 3: 9, 4: 16 } 2. The order of callback arguments is weird Let’s compare the callbacks of map(), filter(), find(), and reduce(): : (currentValue, index, array, this) => {} map : (currentValue, index, array, this) => {} filter : (currentValue, index, array, this) => {} find (accumulator, currentValue, index, array) => {} reduce: Your callback will get the accumulator as the argument, not the currentValue; also, there is no parameter that takes a argument. first this 3. Error: myVar.reduce is not a function I’ve been spoiled by , which treats both arrays and objects as collections, and collections have map, find, filter, and reduce methods. Not so JavaScript reduce: lodash var obj1 = {my:"dog", has: "fleas"}; const values = (accumulator, currentValue) => accumulator.push(currentValue); console.log(obj1.reduce(values, [])); // > Error: obj1.reduce is not a function As Dana Carvey used to say, “Nope, not gonna do it. Wouldn’t be prudent.” (Yes, I am that old.) You can still do something like this, using Object.values or Object.entries: var obj1 = {my:"dog", has: "fleas"}; const values = (acc, [key, value]) => {acc.push(value); return acc} console.log(Object.entries(obj1).reduce(values, [])); // > Array ["dog", "fleas"] 4. Accumulator sometimes optional; results sometimes random It’s easy to forget an initial accumulator value, even when you need one. Let’s take that above example, with one modification: var obj1 = {my:"dog", has: "fleas"}; const values = (acc, [key, value]) => {acc.push(value); return acc} console.log(Object.entries(obj1).reduce(values)); // > Array ["my", "dog", "fleas"] Did you notice the difference in the code? Hard to spot. What’s worse, you get an array of values back, except the first is invalid. Good thing I have tests someday! 5. Undefined? Huh? Oh, you forgot to return the accumulator. Silly you. I make that mistake: never var obj1 = {my:"dog", has: "fleas"}; const dog = (acc, [key, value]) => { if (key === 'my') { acc.push(value); return acc; } } console.log(Object.entries(obj1).reduce(dog, [])); // > undefined You have to always return the accumulator: var obj1 = {my:"dog", has: "fleas"}; const dog = (acc, [key, value]) => { if (key === 'my') { acc.push(value); } return acc; } console.log(Object.entries(obj1).reduce(dog, [])); So what do I recommend instead of reduce()? I am using Array.reduce(), and you should, too. Just know its quirks. It’s like a tiny chihuahua nipping at your heels that sometimes will get you if you’re not paying attention, but it’s mostly harmless (and far more useful than a chihuahua). always Happy reducing! <a href="https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href">https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href</a>