亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

深入學習JavaScript 高階函數

2024-05-06 16:52:03
字體:
來源:轉載
供稿:網友

高階函數

高階函數英文叫 Higher-order function,它的定義很簡單,就是至少滿足下列一個條件的函數:

  • 接受一個或多個函數作為輸入
  • 輸出一個函數

也就是說高階函數是對其他函數進行操作的函數,可以將它們作為參數傳遞,或者是返回它們。 簡單來說,高階函數是一個接收函數作為參數傳遞或者將函數作為返回值輸出的函數。

函數作為參數傳遞

JavaScript 語言中內置了一些高階函數,比如 Array.prototype.map,Array.prototype.filter 和 Array.prototype.reduce,它們接受一個函數作為參數,并應用這個函數到列表的每一個元素。我們來看看使用它們與不使用高階函數的方案對比。

Array.prototype.map

map() 方法創建一個新數組,其結果是該數組中的每個元素都調用一個提供的函數后返回的結果,原始數組不會改變。傳遞給 map 的回調函數(callback)接受三個參數,分別是 currentValue、index(可選)、array(可選),除了 callback 之外還可以接受 this 值(可選),用于執行 callback 函數時使用的this 值。

來個簡單的例子方便理解,現在有一個數組 [1, 2, 3, 4],我們想要生成一個新數組,其每個元素皆是之前數組的兩倍,那么我們有下面兩種使用高階和不使用高階函數的方式來實現。

不使用高階函數

// 木易楊const arr1 = [1, 2, 3, 4];const arr2 = [];for (let i = 0; i < arr1.length; i++) {arr2.push( arr1[i] * 2);}console.log( arr2 );// [2, 4, 6, 8]console.log( arr1 );// [1, 2, 3, 4]

使用高階函數

// 木易楊const arr1 = [1, 2, 3, 4];const arr2 = arr1.map(item => item * 2);console.log( arr2 );// [2, 4, 6, 8]console.log( arr1 );// [1, 2, 3, 4]

Array.prototype.filter

filter() 方法創建一個新數組, 其包含通過提供函數實現的測試的所有元素,原始數組不會改變。接收的參數和 map 是一樣的,其返回值是一個新數組、由通過測試的所有元素組成,如果沒有任何數組元素通過測試,則返回空數組。

來個例子介紹下,現在有一個數組 [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4],我們想要生成一個新數組,這個數組要求沒有重復的內容,即為去重。

不使用高階函數

const arr1 = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];const arr2 = [];for (let i = 0; i < arr1.length; i++) {if (arr1.indexOf( arr1[i] ) === i) {arr2.push( arr1[i] );}}console.log( arr2 );// [1, 2, 3, 5, 4]console.log( arr1 );// [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]

使用高階函數

const arr1 = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];const arr2 = arr1.filter( (element, index, self) => {return self.indexOf( element ) === index;});console.log( arr2 );// [1, 2, 3, 5, 4]console.log( arr1 );// [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]

Array.prototype.reduce

reduce() 方法對數組中的每個元素執行一個提供的 reducer 函數(升序執行),將其結果匯總為單個返回值。傳遞給 reduce 的回調函數(callback)接受四個參數,分別是累加器 accumulator、currentValue、currentIndex(可選)、array(可選),除了 callback 之外還可以接受初始值 initialValue 值(可選)。

  • 如果沒有提供 initialValue,那么第一次調用 callback 函數時,accumulator 使用原數組中的第一個元素,currentValue 即是數組中的第二個元素。 在沒有初始值的空數組上調用 reduce 將報錯。
  • 如果提供了 initialValue,那么將作為第一次調用 callback 函數時的第一個參數的值,即 accumulator,currentValue 使用原數組中的第一個元素。

來個簡單的例子介紹下,現在有一個數組 [0, 1, 2, 3, 4],需要計算數組元素的和,需求比較簡單,來看下代碼實現。

不使用高階函數

const arr = [0, 1, 2, 3, 4];let sum = 0;for (let i = 0; i < arr.length; i++) {sum += arr[i];}console.log( sum );// 10console.log( arr );// [0, 1, 2, 3, 4]

使用高階函數

無 initialValue 值

const arr = [0, 1, 2, 3, 4];let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {return accumulator + currentValue;});console.log( sum );// 10console.log( arr );// [0, 1, 2, 3, 4]

上面是沒有 initialValue 的情況,代碼的執行過程如下,callback 總共調用四次。

callback accumulator currentValue currentIndex array return value
first call 0 1 1 [0, 1, 2, 3, 4] 1
second call 1 2 2 [0, 1, 2, 3, 4] 3
third call 3 3 3 [0, 1, 2, 3, 4] 6
fourth call 6 4 4 [0, 1, 2, 3, 4] 10
 

有 initialValue 值

我們再來看下有 initialValue 的情況,假設 initialValue 值為 10,我們看下代碼。

const arr = [0, 1, 2, 3, 4];let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {return accumulator + currentValue;}, 10);console.log( sum );// 20console.log( arr );// [0, 1, 2, 3, 4]

代碼的執行過程如下所示,callback 總共調用五次。

callback accumulator currentValue currentIndex array return value
first call 10 0 0 [0, 1, 2, 3, 4] 10
second call 10 1 1 [0, 1, 2, 3, 4] 11
third call 11 2 2 [0, 1, 2, 3, 4] 13
fourth call 13 3 3 [0, 1, 2, 3, 4] 16
fifth call 16 4 4 [0, 1, 2, 3, 4] 20

 

函數作為返回值輸出

這個很好理解,就是返回一個函數,下面直接看兩個例子來加深理解。

isType 函數

我們知道在判斷類型的時候可以通過 Object.prototype.toString.call 來獲取對應對象返回的字符串,比如:

let isString = obj => Object.prototype.toString.call( obj ) === '[object String]';let isArray = obj => Object.prototype.toString.call( obj ) === '[object Array]';let isNumber = obj => Object.prototype.toString.call( obj ) === '[object Number]';

可以發現上面三行代碼有很多重復代碼,只需要把具體的類型抽離出來就可以封裝成一個判斷類型的方法了,代碼如下。

let isType = type => obj => {return Object.prototype.toString.call( obj ) === '[object ' + type + ']';}isType('String')('123'); // trueisType('Array')([1, 2, 3]); // trueisType('Number')(123); // true

這里就是一個高階函數,因為 isType 函數將 obj => { ... } 這一函數作為返回值輸出。

add 函數

我們看一個常見的面試題,用 JS 實現一個無限累加的函數 add,示例如下:

add(1); // 1add(1)(2); // 3add(1)(2)(3); // 6add(1)(2)(3)(4); // 10 // 以此類推

我們可以看到結構和上面代碼有些類似,都是將函數作為返回值輸出,然后接收新的參數并進行計算。

我們知道打印函數時會自動調用 toString()方法,函數 add(a) 返回一個閉包 sum(b),函數 sum() 中累加計算 a = a + b,只需要重寫sum.toString()方法返回變量 a 就可以了。

function add(a) {function sum(b) { // 使用閉包a = a + b; // 累加return sum;}sum.toString = function() { // 重寫toString()方法return a;}return sum; // 返回一個函數}add(1); // 1add(1)(2); // 3add(1)(2)(3); // 6add(1)(2)(3)(4); // 10 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性xxxx极品hd欧美风情| 在线看日韩av| 久久五月情影视| 欧美激情免费在线| 成人欧美在线观看| 久久久精品免费视频| 久久精品国产亚洲精品2020| 欧美色欧美亚洲高清在线视频| 亚洲视频在线免费观看| 青草青草久热精品视频在线网站| 91深夜福利视频| 2024亚洲男人天堂| 久久天天躁狠狠躁老女人| 国产精品三级在线| 久久精品电影网站| 免费不卡在线观看av| 久久精品免费电影| 青草青草久热精品视频在线网站| 91精品国产综合久久香蕉最新版| 国产ts人妖一区二区三区| 日韩av色综合| 国产精品国产福利国产秒拍| 91夜夜揉人人捏人人添红杏| 精品国产一区二区在线| 亚洲裸体xxxx| 51午夜精品视频| 欧美激情一二三| 美女福利精品视频| 国产精品在线看| 国产精品最新在线观看| 欧美激情二区三区| 精品久久久久久久久中文字幕| 久久精品国产亚洲精品2020| 欧美一级视频一区二区| 91系列在线观看| 91亚洲国产精品| 国产亚洲欧美aaaa| 亚洲香蕉伊综合在人在线视看| 日韩av不卡电影| 高清在线视频日韩欧美| 亚洲黄色av女优在线观看| 亚洲人成77777在线观看网| 日韩av网站在线| 日韩a**站在线观看| 亚洲精美色品网站| 久久露脸国产精品| 国产精品日韩欧美大师| 日产精品99久久久久久| 日韩在线高清视频| 国产精品爱久久久久久久| 国产成人精品视频| 日本精品久久电影| 国产成人亚洲综合青青| 亚洲精品自拍视频| 国产亚洲成av人片在线观看桃| 久久免费精品日本久久中文字幕| 日韩av综合中文字幕| 91色琪琪电影亚洲精品久久| 中文字幕精品一区二区精品| 国内外成人免费激情在线视频网站| 精品呦交小u女在线| 久久亚洲精品中文字幕冲田杏梨| 精品无人区太爽高潮在线播放| 欧美视频精品一区| 国产精品99久久久久久久久久久久| 亚洲成人久久网| www日韩中文字幕在线看| 欧美日韩成人网| 亚州国产精品久久久| 久久久噜久噜久久综合| 欧美中文字幕在线视频| 国产精品久久久久久久午夜| 午夜精品一区二区三区av| 精品国产91久久久久久老师| 久99九色视频在线观看| 国产精品久久综合av爱欲tv| 在线观看欧美www| 欧美老女人在线视频| 亚洲精品久久久久久久久久久久| 亚洲午夜色婷婷在线| 永久免费看mv网站入口亚洲| 久久久精品视频在线观看| 亚洲第五色综合网| 亚洲美女免费精品视频在线观看| 一本色道久久88综合亚洲精品ⅰ| 欧美日韩精品在线播放| 亚洲国产成人精品女人久久久| 欧美精品在线免费| 国产亚洲精品久久久久久牛牛| 欧美精品激情在线| 欧美亚洲成人精品| 欧美第一页在线| 欧美极品少妇xxxxⅹ免费视频| 国产日韩精品在线| 久久99亚洲热视| 91色在线观看| 日韩av在线免费观看| 国产精品成人一区二区| 日韩免费观看在线观看| 蜜臀久久99精品久久久久久宅男| 久久精品久久久久久国产 免费| 国产在线观看不卡| 欧美性猛交xxxx免费看漫画| 亚洲国产精品高清久久久| 岛国av一区二区三区| 亚洲白虎美女被爆操| 久久久久久久久久国产精品| 色视频www在线播放国产成人| 在线视频欧美日韩| 亚洲成人精品视频在线观看| 色偷偷av亚洲男人的天堂| 亚洲第一网中文字幕| 亚洲精品日韩在线| 日本一区二三区好的精华液| 久久精品国产综合| 4p变态网欧美系列| 久久久久成人网| 日韩国产精品视频| 亚洲美女av电影| 亚洲第一精品夜夜躁人人躁| 国产精品福利小视频| 欧美一二三视频| 这里精品视频免费| 国产亚洲欧美另类中文| 国产精品久久久久影院日本| 91青草视频久久| 久久久久久中文| 日韩中文字幕在线看| 色综合久久88| 隔壁老王国产在线精品| 亚洲精品福利视频| 欧美激情一区二区三区高清视频| 一本色道久久综合亚洲精品小说| 日本亚洲欧洲色| 国产精品美女久久久免费| 不卡伊人av在线播放| 久久久噜噜噜久噜久久| 精品国产999| 成人国产亚洲精品a区天堂华泰| 欧美日韩福利电影| 国产日韩欧美夫妻视频在线观看| 日韩欧美国产视频| 日韩视频免费中文字幕| 欧美大全免费观看电视剧大泉洋| 欧美大片va欧美在线播放| 亚洲性日韩精品一区二区| 中文字幕日本精品| 国产精品入口免费视频一| 欧美亚洲国产精品| 在线观看日韩专区| 91国内产香蕉| 欧美成人免费在线视频| 成人亲热视频网站| 蜜臀久久99精品久久久无需会员| 亚洲精品欧美日韩| 日本免费久久高清视频| 91高清视频免费观看| 日韩精品在线视频观看| 欧美二区在线播放| 欧美精品在线免费播放| 日韩免费在线看| 98视频在线噜噜噜国产| 亚洲精品日韩欧美| 欧美日韩高清在线观看|