High order functions on Array.prototype In order to better understand functional programming in Javascript, I thought I'd try to recreate (as well as extend) some of the higher order functions on the Array object. These methods don't intend to be identical but to have the basic functionality. Any tips/suggestions/feedback would be greatly appreciated!

// Array.prototype.map()
Array.prototype.newMap = function(fn) {
    var returnedArray = [];

    for (var i = 0; i &lt; this.length; i++) {
        returnedArray[i] = fn(this[i]);
    }
    return returnedArray;
};

// newMap for multi-dimensional arrays
Array.prototype.newMapMulti = function(fn) {
    var mainArray = [];

    for (var i = 0; i &lt; this.length; i ++) {
        var result = this[i].newMap(fn);
        mainArray.push(result);
    }
    return mainArray;
};

// Array.prototype.filter()
Array.prototype.newFilter = function(fn) {
    var returnedArray = [];

    for (var i = 0; i &lt; this.length; i++) {
        var c = this[i];

        if (fn(c)) {
            returnedArray.push(c);
        }
    }
    return returnedArray;
};
// newFilter for multi-dimensional arrays
Array.prototype.newFilterMulti = function(fn) {
    var mainArray = [];

    for (var i = 0; i &lt; this.length; i++) {
        var result = this[i].newFilter(fn);
        if (result.length === 0) { continue }
        mainArray.push(result);
    }
    return mainArray;
};

// Array.prototype.find()
Array.prototype.newFind = function(fn) {

    for (var i = 0; i &lt; this.length; i++) {
        var c = this[i];

        if (fn(c)) {
            return c;
        }
    }
};

// Array.prototype.reduce()
Array.prototype.newReduce = function(fn) {
    var total = 0;

    for (var i = 0; i &lt; this.length; i++) {
        total += fn(this[i]);
    }
    return total;

};

// newReduce for multi-dimensional arrays
Array.prototype.newReduceMulti = function(fn) {
    var total = 0;

    for (var i = 0; i &lt; this.length; i++) {
        total += this[i].newReduce(fn);
    }
    return total;
};

// returns a reduce value. if fn1 returns a value &lt; x, then apply fn2 and return that value
Array.prototype.newReduceIf = function(fn1, fn2, x) {
    var reduceResult = this.newReduce(fn1);

    if (reduceResult &lt; x) {
        var secondResult = this.newReduce(fn2);
        return secondResult;
    }  
    return reduceResult;
};
First, it's not recommended to extend native objects. That's because modifying the prototype applies to all instances. Now let's say the spec added a newMap method that acted differently from your implementation. Code that uses newMap according to spec (like third party code) will break because your code overrides the native implementation and operates in a totally different way.

That's one reason why libraries like lodash and underscore don't extend native objects, and just accept the array/object as an argument. They also provide "wrapping" mechanisms, accepting an array and wrapping it in a container object with its own prototype methods. That way, they safely add methods without modifying native objects while keeping it looking like they extend.

// In lodash, the _ function wraps the array in a "lodash object" which
// has methods like map etc.
var newValues = _([1,2,3]).map(v =&gt; v * 3).value(); // [3,6,9]

// In jQuery, the $ function wraps the element in a "jQuery object" which
// has its own DOM manipulation methods.
$(document.getElementById('myElement')).remove();


Now let's say you didn't extend it via native objects.

newFilterMulti isn't really a true multi-dimensional array filter. It only appears to go 2 levels deep (2D). Either you make it a true multi-dimensional filter (going as deep as it can) or rename it so it's more apparent that it only goes 2 levels deep.

newReduce doesn't act the same way native reduce works (and this is a good example of spec-breaking implementation). reduce doesn't add return values. It carries over the last result to the next call regardless of type. This means the callback accepts 2 values, the carry and the current value. Also, most reduce implementations accept an initial argument for the carry value. If omited, reduce starts at the second element in the array, with the first element as carry.

Again, newReduceMulti isn't a true multi-dimensional reduce, just 2D. Re-implement or rename accordingly.

Now one technique used by most libraries is to reuse the operations that have already been defined. In the case of jQuery, internally it makes heavy use of its $.each. So if they need anything looped through, instead of tediously writing for loops everywhere, they use their $.each. Also, I heard FP operations rely heavily on map.

So if you could make a solid forEach and map implementation, you can readily reuse them in your other methods instead of writing a for loop every time.