Reputation: 140
This example is from http://eloquentjavascript.net/code/#5.1. My question is the first bullet-pointed detail; others may be helpful details, but are additional; also see the first short program to see my question in context.
arrays.reduce()
used instead of reduce(arrays())
. I know that their's works with the arrays.reduce
, but why?This is an answer to a comment that is useful, but additional to the original question.
This is the program with the context of my question-
var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(arrays.reduce(function(flat, current) {
return flat.concat(current);
}, []));
// → [1, 2, 3, 4, 5, 6]
These next details are additional, but may(or may not) be of use:
I know that the []
at the end is used because it is the start parameter in the function reduce so that the other arrays are added to that empty array. I know the .concat
is putting together the two arrays like +
with strings, but for arrays. Here is what the reduce function, even though it is standard, looks like:
function reduce(array, combine, start){
var current = start;
for(var i = 0; i < array.length; i++)
current = combine(current, array[i]);
return current;
}
One of their other examples showed my way with a single array, if that helps. It looked like:
console.log(reduce([1, 2, 3, 4], function(a, b){
return a + b;
}, 0));
// 10
Thanks! :)
Upvotes: 1
Views: 343
Reputation: 707386
In object oriented design, a guiding principle is that you create or declare objects and those objects have a series of methods on them that operate on that particular type of object. As Javascript is an object oriented language, the built-in functions follow many of the object oriented principles.
.reduce()
is a function that operates only on Arrays. It is of no use without an Array to operate on. Thus, in an object oriented design paradigm, it makes complete sense to place the .reduce()
function as a method on an Array
object.
This object-oriented approach offers the following advantages vs. a global reduce()
function:
.reduce()
function on a particular array
by using array.reduce()
and it is obvious from the syntax which array it is operating on.Array
object making the API definition more self documenting.obj.reduce()
(invoke it on a non-array), you will immediately get an runtime error about an undefined .reduce()
method.If you want to know why anyone ever used a global reduce()
instead, you would need to understand a little bit about the history of Javascript evolution. Before ES5 (or for users running browsers who hadn't yet implemented ES5 like IE8), Javascript did not have a built-in .reduce()
method on the Array
object. Yet, some developers who were familiar with this type of useful iteration capability from other languages wanted to to use it in their own Javascript or in their own Javascript framework.
When you want to add some functionality to an existing built-in object like Array
in Javascript, you generally have two choices. You can add a method to the prototype (in object-oriented fashion) or you can create a global function that takes the Array
as its first argument.
For the Array
object in particular, there are some potential issues with adding iterable methods to the Array
prototype. This is because if any code does this type of iteration of an array (a bad way to iterate arrays, but nevertheless done by many):
for (var prop in array)
they will end up iterating not only the elements of the array, but also any iterable properties of the array. If a new method is assigned to the prototype with this type of syntax:
Array.prototype.myMethod = function() {}
Then, this new method will end up getting iterated with the for (var prop in array)
syntax and it will often cause problems.
So, rather than adding a new method to the prototype, a safer alternative was to just use a global function and avoid this issue.
Starting in ES 5.1, there is a way using Object.defineProperty()
to add non-iterable methods to an object or prototype so for newer browsers, it is now possible to add methods to a prototype that are not subject to the problem mentioned above. But, if you wanted to support older browsers (like IE8) and use reduce()
type of functionality, you're still stuck with these ancient limitations.
So ... even though a global reduce()
is less object oriented and is generally not as desirable in Javascript, some older code went that route for legitimate safety/interoperability reasons. Fortunately, we are putting that road behind us as old version of IE drop off in usage (thank god for Microsoft dropping XP support to finally accelerate the demise of old versions of IE). And newer browsers already contain array.reduce()
built in.
Upvotes: 2
Reputation: 315
JavaScript was/is influenced by the language Scheme, a dialect of Lisp. In Scheme higher order functions are a key component/feature of the language. In fact the reduce
function is pretty much equivalent to the fold
function in Scheme. In the case of the reduce
function in JavaScript, the creators of the language noticed that programmers often need to traverse arrays in a certain fashion, and gave programmers a higher order function where they can pass in a function to specify how they want to manipulate the data. Having higher order functions allows programmers to abstract redundant code therefore creating shorter, cleaner, more readable code.
You can use the reduce
function in JavaScript to do many things other than flatten lists. Look here an example.
Upvotes: 2