1. 程式人生 > >高階函式及 map、reduce、filter 的實現

高階函式及 map、reduce、filter 的實現

部落格地址:https://ainyi.com/85

2020 開年國家經歷了不少困難,最為凶猛的局勢就是新型冠狀病毒的蔓延,國務院最終決定春節假期延長至==2 月 2 號==;公司決定 3 - 7 號在家用 vpn 辦公。10 號正式在職場上班;

在這個看似漫無止境的春節假期中,在家宅著不出門就是對社會最好的貢獻,那麼一直待在家也確實無聊極致,索性學習學習、看看書吧,再學習學習 JavaScript 的函式吧

函式

函式是函數語言程式設計的工作單元與中心。函式是任何可呼叫你且可通過 () 操作求值的表示式。

JavaScript 函式有兩個支柱性的重要特性:一等函式和高階函式

一等函式就是最常見的,如:

function multiplier(a, b) {
  return a * b
}

let square = function(x) {
  return x * x
}

// lambda 表示式(箭頭函式)
let square = x => x * x

主要說說高階函式

高階函式

鑑於函式的行為與普通物件類似,其理所當然地可以作為其他函式的引數進行傳遞,或是由其他函式返回。這些函式則稱為高階函式。~JavaScript函數語言程式設計指南p36~

例如 Array.sort 的 comparator 函式就是高階函式(傳送門:https://ainyi.com/41 -> sort 函式)

function add(a) {
  return function(b) {
    return a + b
  }
}
add(1)(2)

上面例子,add 函式接收一個引數,並返回另一個接收第二個引數並把它們加在一起的函式

函式柯里化能夠很好地體現高階函式的應用

function currying(fn, length) {
  length = length || fn.length;     
  return function (...args) {           
    return args.length >= length    
        ? fn.apply(this, args)          
      : currying(fn.bind(this, ...args), length - args.length) 
  }
}

const add = currying(function(a, b, c) {
    console.log([a, b, c].reduce((a, b) => a + b))
})

add(1, 2, 3) // 6
add(1, 2)(3) // 6
add(1)(2)(3) // 6
add(1)(2, 3) // 6

相容各種 add 呼叫的高階函式

詳情看我之前寫的文章 js 高階函式之柯里化

map、reduce、filter

此三種函式均為高階函式,如何實現這三個函式,接下來看看。

一般重寫物件的例項方法是通過 prototype,陣列的所有例項方法、屬性都儲存在 Array.prototype。只不過平常都是通過該物件的例項呼叫

通過 _.例項方法,該例項方法的 this 指標指向它

map 的實現

高階函式 map 能夠將一個迭代函式有序地應用於一個數組中的每個元素,並返回一個長度相等的新陣列

function map(fn) {
  let idx = -1,
      len = this.length,
      result = new Array(len)

  while (++idx < len) {
    result[idx] = fn(this[idx], idx, this)
  }
  console.log('myself')
  return result
}
Array.prototype.map = map;
[1, 2, 3].map(ele => `#${ele}#`)
// myself
// ["#1#", "#2#", "#3#"]

reduce 實現

高階函式 reduce 將一個數組中的元素精簡為單一的值,該值是由每個元素與一個累計值通過一個函式計算得出的

function reduce(fn, accumulator) {
  let idx = -1,
      len = this.length

  if (!accumulator && len > 0) {
    accumulator = this[++idx]
  }

  while (++idx < len) {
    accumulator = fn(accumulator, this[idx], idx, this)
  }
  console.log('myself')
  return accumulator
}
Array.prototype.reduce = reduce;
[1, 2, 3].reduce((n, p) => n + p)
// myself
// 6

// 也可以指定第一個累計值
[1, 2, 3].reduce((n, p) => n + p, 100)
// myself
// 106

filter 的實現

高階函式 filter 能夠遍歷陣列中的元素並過濾後返回一個新子集陣列

function filter(fn) {
  let idx = -1,
      len = this.length
      result = []

  while (++idx < len) {
    let value = this[idx]
    if (fn(value, idx, this)) {
      result.push(value)
    }
  }
  console.log('myself')
  return result
}
Array.prototype.filter = filter;
[1, 2, 3].filter(ele => ele >= 2)
// myself
// [2, 3]

部落格地址:https://ainyi.com