Javascript高階函數(shù)

高階函數(shù)

概念

Javascript中的函數(shù)本質(zhì)上都指向某個(gè)變量,既然變量可以指向函數(shù),函數(shù)的參數(shù)可以接受變量,那么函數(shù)是不是可以可以作為另一個(gè)函數(shù)的入?yún)??因?yàn)镴avascript是一門弱類型語言,不會(huì)對(duì)函數(shù)輸入值和函數(shù)的輸出值進(jìn)行強(qiáng)定義和類型檢查。所以函數(shù)可以作為參數(shù),也可以作為輸出值。

一個(gè)最簡(jiǎn)單的高階函數(shù):

let add=(x,y,f)=>f(x)+f(y);

對(duì)其他函數(shù)進(jìn)行操作的函數(shù),可以將他們作為參數(shù)或返回它們。

高階函數(shù)分類

  • 函數(shù)作為參數(shù)傳遞
  • 函數(shù)作為返回值

map/reduce/filter

map

定義:map() 方法返回一個(gè)新數(shù)組,不會(huì)改變?cè)紨?shù)組。同時(shí)新數(shù)組中的元素為原始數(shù)組元素調(diào)用函數(shù)處理后的值,并按照原始數(shù)組元素順序依次處理元素。

語法:array.map(function(currentValue /*必填,當(dāng)前元素的值 */,index /*可選,當(dāng)前元素的索引*/,arr /*可選,當(dāng)前元素屬于的數(shù)組對(duì)象*/), thisValue /*可選,上下文對(duì)象,用作this,默認(rèn)為全局對(duì)象*/)

有以下需求:創(chuàng)建一個(gè)新數(shù)組,其中的值是原數(shù)組的值的兩倍。

const arr=[1,2,3]
let fn=(arr)=>{
  let temp=[]
  for(let i=0;i<arr.length;i++){
    temp.push(arr[i]*2)
  }
  return temp;
}
console.log(fn(arr))

以上是我們的命令式編程,我們改寫下:

const temp=[1,2,3].map(item=>item*2)
console.log(temp)

在這里我們使用(item)=>item*2作為map函數(shù)的參數(shù)。

手動(dòng)實(shí)現(xiàn)map(),遍歷函數(shù)的每一項(xiàng)作為函數(shù)的入?yún)?,并返回每次函?shù)調(diào)用結(jié)果組成的數(shù)組

關(guān)鍵:1.函數(shù)為空,返回空 2.func 必須是函數(shù)類型,需要有return值,否則會(huì)出現(xiàn)所有項(xiàng)映射為undefind 3.無副作用

Array.prototype.mapTest = function (func, content) {
  if (typeof func !== 'function') throw new TypeError(
    `${typeof func} is not a function`)
  let arrTemp = this.slice()
  content = typeof content === 'undefined' ? null : content
  let result = []
  for (let idx = 0; idx < arrTemp.length; idx++) {
    result.push(func.call(content, arrTemp[idx], idx, arrTemp))
  }
  return result
}

reduce

定義:reduce() 方法接收一個(gè)函數(shù)作為累加器,數(shù)組中的每個(gè)值(從左到右)開始縮減,最終計(jì)算為一個(gè)值

語法:array.reduce(function(total /*必需。初始值, 或者計(jì)算結(jié)束后的返回值*/, currentValue/*必需。當(dāng)前元素*/, currentIndex/*可選。當(dāng)前元素的索引*/, arr/*可選。當(dāng)前元素所屬的數(shù)組對(duì)象。*/), initialValue/*可選。傳遞給函數(shù)的初始值*/)

有以下需求:對(duì)數(shù)組arr的項(xiàng)進(jìn)行求和

let arr=[1,2,3,4]

// 命令式編程
let sum=arr=>{
  let temp=0;
  for(let idx=0;idx<arr.length;idx++){
    temp+=arr[idx]
  }
  return temp
}
//使用reduce
let total=arr.reduce((prev,cur)=>{
  return prev+cur
},0)

過程分析:

第一次執(zhí)行時(shí),prev的值為我們的初始值0,返回0+cur(當(dāng)前數(shù)組的第一位)作為第二次執(zhí)行時(shí)的prev….從而達(dá)到累加的目的;

手動(dòng)實(shí)現(xiàn)一個(gè)reduce(),核心就是遍歷數(shù)組每一項(xiàng)參與函數(shù)運(yùn)算并將返回值作為下次遍歷的初始值,從而實(shí)現(xiàn)累加。

關(guān)鍵點(diǎn):1.無初始值時(shí),從原數(shù)組的第二項(xiàng)進(jìn)行遍歷 2.無副作用

Array.prototype.reduceTest = function(func, initVal, directionLeft = true) {
  if (typeof func !== 'function') throw new TypeError(`${typeof func} is not a function`)
  if (!this.length) {
    if (typeof initVal !== 'undefined') {
      return initVal
    } else {
      throw new Error('Reduce of empty array with no initial value')
    }
  }
  let array = this.slice()
  let hasInitVal = typeof initVal !== 'undefined'
  let value = hasInitVal ? initVal : array[0]
  if (directionLeft === false) {
    array = array.reverse()
  }
  for (let idx = hasInitVal ? 0 : 1; idx < array.length; idx++) {
    const cur = array[idx]
    value = func.call(null,value, cur, idx, array)
  }
  return value
}

filter

定義:filter() 方法創(chuàng)建一個(gè)新的數(shù)組,新數(shù)組中的元素是通過檢查指定數(shù)組中符合條件的所有元素。

語法:array.filter(function(currentValue/*必須。當(dāng)前元素的值*/,index/*可選。當(dāng)前元素的索引值*/,arr/*可選。當(dāng)前元素屬于的數(shù)組對(duì)象*/), thisValue/*可選。對(duì)象作為該執(zhí)行回調(diào)時(shí)使用,傳遞給函數(shù),用作 "this" 的值*/)

需求:過濾出對(duì)象數(shù)組中age大于10的元素

let persons = [
  { 'name': 'Bob', age: 12 },
  { 'name': 'Lily', age: 13 },
  { 'name': 'Tom', age: 9 },
  { 'name': 'Jone', age: 99 },
]

// 命令式編程
let result=()=>{
  let res=[];
  for(let idx=0;idx<persons.length;idx++){
    if(persons[idx].age>10){
      res.push(persons[idx])
    }
  }
  return res;
}
// 使用filter
let filterResult=persons.filter(item=>item.age>9);

手動(dòng)實(shí)現(xiàn)一個(gè)filter(),核心就是創(chuàng)建一個(gè)新的數(shù)組,新數(shù)組中的元素是原數(shù)組中符合條件的項(xiàng)

關(guān)鍵點(diǎn):1.函數(shù)返回值為true/false 2.無副作用

Array.prototype.filterTest=function (func,content) {
  if (typeof func !== 'function') throw new TypeError(`${typeof func} is not a function`)
  if (!this.length) return []
  let arr = this.slice()
  content = typeof content === 'undefined' ? null : content
  let result=[]
  for(let idx=0;idx<arr.length;idx++){
    let res=func.call(content,arr[idx],idx,arr)
    if(res){
      result.push(arr[idx])
    }
  }
  return result
}

flat

注意:普通瀏覽器(僅Chrome v69,F(xiàn)irefox Nightly和Opera 56等)/Node.js (需V11.0.0及以上) 尚未實(shí)現(xiàn)flat方法。這是一項(xiàng)實(shí)驗(yàn)性功能。 [MDN 說明以及替代方案]

用法:將目標(biāo)嵌套數(shù)組扁平化,變?yōu)樾碌囊痪S數(shù)組

語法:arrry.flat([depth]/*指定要提取嵌套數(shù)組的結(jié)構(gòu)深度,默認(rèn)值為 1。Infinity為無限*/)

手動(dòng)實(shí)現(xiàn)一個(gè)flat()

/**
 * 數(shù)組扁平化
 * @param depth 拉平深度 默認(rèn)為1,最大為Infinity
 */
Array.prototype.flatTest = function (depth = 1) {
  let arr = this.slice()
  const result = []
  // 當(dāng)前已拉平層數(shù) 
  let flattenDepth = 1;
  // 先拉平第一層
  (function flatten (list) {
    list.forEach((item) => { 
      if (flattenDepth < depth &&Array.isArray(item)) {
        flattenDepth++
        flatten(item)
      } else {
        result.push(item)
      }
    })
  })(arr)
  return result
}

總結(jié)

高階函數(shù)本質(zhì)上就是對(duì)算法的高度抽象,通過提高抽象度,實(shí)現(xiàn)最大程度代碼重構(gòu)

示例代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本期開始介紹 JavaScript 中的高階函數(shù),在 JavaScript 中,函數(shù)是一種特殊類型的對(duì)象,它們是 ...
    編程小世界閱讀 548評(píng)論 0 0
  • 高階函數(shù) 在 JavaScript 中,函數(shù)是一種特殊類型的對(duì)象,它們是 Function objects。高階函...
    PalSylo閱讀 381評(píng)論 1 9
  • 學(xué)習(xí)筆記,非原創(chuàng)。謝謝 高階函數(shù) 高階函數(shù)英文叫Higher-order function。那么什么是高階函數(shù)? ...
    Rising_life閱讀 524評(píng)論 0 8
  • 概念 所謂的高階函數(shù)就是: 函數(shù)可以作為參數(shù) 函數(shù)可以作為返回值 filter 上面的代碼很簡(jiǎn)單,上面代碼只是為了...
    無跡落花閱讀 602評(píng)論 0 3
  • 一、數(shù)組 1.concat( )用途:合并數(shù)組;不改變現(xiàn)有數(shù)組,返回新數(shù)組;參考:MDN array.concat...
    Summer_zxm閱讀 514評(píng)論 0 1

友情鏈接更多精彩內(nèi)容