After array.prototype.reduce, I am determined to study hard. Pondering for a long time, plus recently read a few “JS functional programming “articles and books, and then feel and write this article.

The array.prototype. map method is familiar, and I’m sure many of you have already implemented the map function yourself. Haven’t implemented your own map? It doesn’t matter. Let’s do it with a for loop.

  Array.prototype.selfMap = function () {
      const ary = this
      const result = new Array(ary.length);
      const [ fn, thisArg ] = [].slice.call(arguments)
      if (typeoffn ! = ='function') {
        throw new TypeError(fn + 'is not a function')}for (let i = 0; i < ary.length; i++) {
        // fix the sparse array case
        if (i inary) { result[i] = fn.call(thisArg, ary[i], i, ary); }}return result
  }
  
  const a = new Array(1.2.3.4)
  a.selfMap(item= > item + 1) // [2, 3, 4, 5]
Copy the code

Implementing your own map is still a pleasure.

However, this is irrelevant to this article because I am implementing Map using Reduce 🤣🤣🤣

As we all know, map functions need to pass a function and an optional this parameter, but I find the second parameter rarely used or noticed, and so do I.

[1.2.3].map(function(item) {
    console.log(this)
    return item
}, { msg: 'mapping' })
Copy the code

The 👆 block above not only returns a new array, it also prints three times on the console

 { msg: 'mapping' }
Copy the code

There is a picture there is a truth 👇

Some of you may have used the arrow function to verify my example above and found that it always prints window, like 👇

Then he said to himself, “Impudent boy, how dare you lie to me?” ({MSG: ‘mapping’}})😭

(the default runtime environment supports array.prototype. reduce, if not 🔨)

    // Do not write the method on the Array prototype this time
    const reduceMap = (fn, thisArg ThisArg */ thisArg */ ) = > {
        return (list) = > {
            // Don't feel like writing the following two judgment conditions
            if (typeoffn ! = ='function') {
                throw new TypeError(fn + 'is not a function'); 
            }
            if (!Array.isArray(list)) {
                throw new TypeError('list must be a Array');
            }
            if (list.length === 0) return [];
            const result = new Array(list.length);
            return list.reduce((acc, value, index) = > {
                // fix the sparse array case
                if (index in list) {
                    acc[index] = fn.call(thisArg, value, index, list);
                }
                returnacc; }, result); }}How about 🧐
    
    reduceMap(x= > x + 1) ([1.2.3 ]) // [2, 3, 4]
    
    const mapAry1 = reduceMap(function(item) {
        console.log(this)
        return item + 1
    }, { msg: 'mapping'}) ([1.2.3 ]) 
    // [2, 3, 4]
    // logging { msg: 'mapping' } three times
Copy the code

👆 implementation of the principle I believe we should all understand it.

While the iron is hot, continue to implement filter.

  • Implementation of the for loop
Array.prototype.selfFilter = function () {
    const ary = this
    const result = []
    const [ fn , thisArg ] = [].slice.call(arguments)
    
    if (typeoffn ! = ='function') {
        throw new TypeError(fn + 'is not a function')}const result = [];
    for (let i = 0; i < ary.length; i++) {
        if (i in ary && fn.call(thisArg, ary[i], i, ary)) {
            result.push(ary[i])
        }
    }
    return result
}

const a = new Array(1.2.3)
a.selfFilter(item= > item % 2= = =0) / / [2]
a.selfFilter(function (item) {
    console.log(this)
    return item % 2= = =0
}, {})
/ / [2]
// logging {} three times
Copy the code
  • Reduce implementation version
// Same as map, not defined on Array prototype
const reduceFilter = (fn, thisAry /* thisAry knows you hate it */ ) = > {
    return (list) = > {
        if (typeoffn ! = ='function') {
            throw new TypeError(fn + 'is not a function')}if (!Array.isArray(list)) {
            throw new TypeError('list must be a Array')}if (list.length === 0) return []
        return list.reduce((acc, value, index) = > {
            return index in ary && fn.call(thisAry, value, index, list) ? acc.concat([ value ]) : acc
        }, [])
    }    
}

reduceFilter(x= > x % 2= = =0) ([1.2.3 ]) / / [2]

Copy the code

There’s a little bit of functional programming in the article, because I’ve only been learning functional programming for a while, and I’m no longer embarrassing myself to the big boys. If there is any wrong or inaccurate writing in the article, or feel that there is a bad place to write, please correct, also let me correct.