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

首頁 > 語言 > JavaScript > 正文

javascript函數式編程程序員的工具集

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

函數式編程語言一向被認為是比其它編程語言更高深的語言。一是因為函數式編程語言的語法很另類,比如Lisp語言,二是因為函數式編程語言都很古老,比如Schema語言。在如今面向對象語言大行其道的時代,函數式編程語言有其特殊的優勢

如果你仔細看了到目前為止出現過的示例代碼,你會發現這里面的一些方法不太熟悉。 它們是map()、filter()和reduce()函數,它們對任何語言的函數式編程都至關重要。 它們可以讓你不必使用循環和語句,寫出更簡潔的代碼。

map()、filter()和reduce()函數組成了函數式程序員工具集的核心部分,這個工具集包括一系列純的、 高階的函數,它們是函數式方法的主力。實際上,它們是純函數和高階函數的典型,它們以一個函數為輸入, 返回一個輸出結果,并且不產生副作用。

然而它們是瀏覽器中ECMAScript 5.1的實現標準,它們只工作于數組。每次調用它們,一個新的數組會被創建并返回, 而原來存在的那個數組不會被改變。它們以函數為輸入,經常使用匿名函數作為回調函數。它們遍歷數組, 并對數組的每一個元素應用這個函數!

 

 
  1. myArray = [1,2,3,4]; 
  2. newArray = myArray.map(function(x) {return x*2}); 
  3. console.log(myArray); // Output: [1,2,3,4] 
  4. console.log(newArray); // Output: [2,4,6,8] 

還有一點,它們只作用于數組,無法作用于其它可迭代的數據結構,比如對象。不用擔心, 有很多庫比如Underscore.js,Lazy.js,stream.js等等都實現了它們自己的更強大的map()、 filter()和reduce()。

回調

如果你以前從來沒用過回調,那這個概念可能會讓你有些迷惑。尤其是在Javascript中, Javascript給出了好幾種聲明函數的方式。

回調函數用于傳遞給另外一個函數供它們使用,這是一種像傳遞對象一樣來傳遞邏輯的方式:

 

 
  1. var myArray = [1,2,3]; 
  2. function myCallback(x){return x+1}; 
  3. console.log(myArray.map(myCallback)); 

對于比較簡單的任務可以用匿名函數:

 

 
  1. console.log(myArray.map(function(x){return x+1})); 

回調不僅用于函數式編程,在Javascript中它們能干很多事情。僅作為例子,這有個callback()函數用于jQuery的AJAX調用:

 

 
  1. function myCallback(xhr) { 
  2. console.log(xhr.status); 
  3. return true
  4. $.ajax(myURI).done(myCallback); 

注意這里只用了函數的名字,因為我們并不是要調用函數而是傳遞函數,寫成這樣就錯了:

 

 
  1. $.ajax(myURI).fail(myCallback(xhr));  
  2. // 或者 
  3. $.ajax(myURI).fail(myCallback()); 

如果我們調用了函數會發生什么?在這個例子里,myCallback(xhr)會嘗試執行,控制臺將打印“undefined”, 并會返回true。當ajax()完成調用時,它根據名字找到的回調函數將是一個"true",然后就報錯了。

也就是說我們無法指定給回調函數傳什么參數,如果我們的回調函數需要讓ajax()函數傳給他我們想要的參數, 我們可以把回到函數包在一個匿名函數里:

 

 
  1. function myCallback(status) { 
  2. console.log(status); 
  3. return true
  4. $.ajax(myURI).done(function(xhr) { 
  5. myCallback(xhr.status) 
  6. }); 

Array.prototype.map()

map()是這些函數的老大,它簡單地對數組里的元素依此應用回調函數。

語法:arr.map(callback [, thisArg]);

參數:

•callback(): 這個函數為新數組產生一個元素,它接收的參數: ?currentValue:數組當前遍歷到的元素

?index:數組中當前元素序數

?array:當前正在處理的數組

•thisArg:這是個可選參數,當執行回調的時候它作為回調函數的this

例子:

 

 
  1. var 
  2. integers = [1, -0, 9, -8, 3], 
  3. numbers = [1, 2, 3, 4], 
  4. str = 'hello world how ya doing?'
  5.  
  6. // 將整數映射為他們自己的絕對值 
  7. console.log(integers.map(Math.abs)); 
  8.  
  9. // 將數組中的元素與自己的位置序數相乘 
  10. console.log(numbers.map(function(x, i) { 
  11. return x * i 
  12. })); 
  13. // 單詞隔一個變一個大寫 
  14. console.log(str.split(' ').map(function(s, i) { 
  15. if (i % 2 == 0) 
  16. return s.toUpperCase(); 
  17. else 
  18. return s; 
  19. })); 

盡管Array.prototype.map方法是Javascript中數組對象的標準方法,你也可以很容易地擴展自己的對象。

 

  1. MyObject.prototype.map = function(f) { 
  2. return new MyObject(f(this.value)); 
  3. };  

Array.prototype.filter()

filter()函數用于把數組中的一些元素篩選出來?;卣{函數必須返回真(保留到新數組里)或假(扔掉)。 用map()可以做類似的事情,就是把你像扔掉的元素返回為null,不過filter()函數會在新數組里面刪除這些不要的元素, 而不是留個null占著位置。

語法:arr.filter(callback [, thisArg]);

•callback():這個函數用來測試數組中的每個元素,要保留返回真,否則返回假。它有這些參數: ?currentValue:數組當前遍歷到的元素

?index:數組中當前元素的序數

?array:當前正在處理的數組

•thisArg:這是個可選參數,當執行回調的時候它作為回調函數的this

例子:

 

 
  1. var myarray = [1, 2, 3, 4] 
  2. words = 'hello 123 world how 345 ya doing'.split(' '); 
  3. re = '[a-zA-Z]'
  4. // 篩選整數 
  5. console.log([-2, -1, 0, 1, 2].filter(function(x) { 
  6. return x > 0 
  7. })); 
  8. // 篩選所有含字母的單詞 
  9. console.log(words.filter(function(s) { 
  10. return s.match(re); 
  11. })); 
  12. // 隨機移除數組中的元素 
  13. console.log(myarray.filter(function() { 
  14. return Math.floor(Math.random() * 2) 
  15. })); 

Array.prototype.reduce()

reduce()函數,有時也稱為fold,它用于把數組中的所有值聚集到一起。回調需要返回組合對象的邏輯。 對于數字來說,它們往往會被加到一起或者乘到一起。對于字符串來說,它們往往是被追加到一起。

語法:arr.reduce(callback [, initialValue]);

參數

•callback():此函數把兩個對象合并成一個對象,并將其返回。參數有: ?previousValue:上一次回調函數被調用時返回的值,或者是初始值(如果有的話)

?currentValue:數組當前正在處理的元素

?index:數組中當前元素的序數

?array:當前正在處理的數組

•initialValue:可選。第一次回調所傳入參數的初始值

例子

 

 
  1. var numbers = [1, 2, 3, 4]; 
  2.  
  3. // 把數組中所有的值加起來 
  4. console.log([1, 2, 3, 4, 5].reduce(function(x, y) { 
  5. return x + y 
  6. }, 0)); 
  7.  
  8. // 查找數組中最大的值 
  9. console.log(numbers.reduce(function(a, b) { 
  10. return Math.max(a, b) // max()函數只能有兩個參數 
  11. })  
  12. ); 

其它函數

map()、filter()和reduce()函數在我們輔助函數的工具箱里并不孤單。這里還有更多的函數幾乎在所有函數式應用里都會被使用。

Array.prototype.forEach

forEach()函數本質上是map()函數的非純版本,它會遍歷整個數組,并對每個元素應用回調。 然而這些回調函數不返回值。它是實現for循環的一個更純粹的方式。

語法:arr.forEach(callback [, thisArg]);

參數:

•callback():對數組中每一個元素所應用的。參數有: ?currentValue:數組中當前正在處理的元素

?index:數組中當前元素的序數

?array:正在處理的數組

•thisArg:可選。回調函數中作為this的值

例子:

 

 
  1. var arr = [1, 2, 3]; 
  2. var nodes = arr.map(function(x) { 
  3. var elem = document.createElement("div"); 
  4. elem.textContent = x; 
  5. return elem; 
  6. }); 
  7.  
  8. // 對每一個元素的值輸出日志 
  9. arr.forEach(function(x) { 
  10. console.log(x) 
  11. }); 
  12.  
  13. // 把節點追加到DOM上 
  14. nodes.forEach(function(x) { 
  15. document.body.appendChild(x) 
  16. }); 

Array.prototype.concat

如果不用for或while處理數組,你會經常需要把數組拼接起來。另一個Javascript內建函數concat就是專門干這事兒的。 concat函數會返回一個新數組但不改變舊數組。它可以把你傳入的所有參數拼接到一起。

console.log([1, 2, 3].concat(['a','b','c']) // 拼接兩個數組

// Output: [1, 2, 3, 'a','b','c']

它返回兩個數組拼接成的數組,同時原來的那些數組沒有被改變。這就意味著concat函數可以鏈式調用。

 

 
  1. var arr1 = [1,2,3]; 
  2. var arr2 = [4,5,6]; 
  3. var arr3 = [7,8,9]; 
  4. var x = arr1.concat(arr2, arr3); 
  5. var y = arr1.concat(arr2).concat(arr3)); 
  6. var z = arr1.concat(arr2.concat(arr3))); 
  7. console.log(x); 
  8. console.log(y); 
  9. console.log(z); 

變量x、y、z的值最后都是[1,2,3,4,5,6,7,8,9]。

Array.prototype.reverse

這個Javascript內建函數是用于數組變形的。reverse函數用于將一個數組反轉,也就是第個一元素會跑到最后, 而最后一個元素變成了第一個元素。

然而,這個函數并不會返回一個新的數組,而是把原來的數組替換掉了。我們可以做個更好的。下面是一個純的反轉數組函數

 

 
  1. var invert = function(arr) { 
  2. return arr.map(function(x, i, a) { 
  3. return a[a.length - (i + 1)]; 
  4. }); 
  5. }; 
  6. var q = invert([1, 2, 3, 4]); 
  7. console.log(q); 

Array.prototype.sort

與map()、filter()和reduce()函數相似,排序函數sort()需要傳入一個回調函數來定義數組如何排序。 但是,跟reverse()一樣,它也會把原來的數組替換。這可不太好。

arr = [200, 12, 56, 7, 344];

console.log(arr.sort(function(a,b){return a–b}) );

// arr現在是: [7, 12, 56, 200, 344];

我們可以寫一個純函數的sort(),但是排序算法的源代碼很麻煩。對于特別大的數組,應當根據特定的數據結構來選用適合的算法, 比如快速排序、合并排序、冒泡排序等等。

Array.prototype.every 和 Array.prototype.some

Array.prototype.every() 和 Array.prototype.some() 都是純的高階函數,它們是Array對象的方法, 通過回調函數根據數組各元素返回的布爾值(或相當于布爾的值)來進行測試。如果數組中所有的元素通過回調函數計算都返回True, every()函數就返回true;如果數組中有一個元素返回True,some()函數就返回True。

例子:

 

 
  1. function isNumber(n) { 
  2. return !isNaN(parseFloat(n)) && isFinite(n); 
  3. console.log([1, 2, 3, 4].every(isNumber)); // Return: true 
  4. console.log([1, 2, 'a'].every(isNumber)); // Return: false 
  5. console.log([1, 2, 'a'].some(isNumber)); // Return: true 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品免费一区| 色无极影院亚洲| 亚洲女人天堂色在线7777| 黄色一区二区三区| 欧美激情xxxxx| 国产精品欧美日韩一区二区| 色哟哟亚洲精品一区二区| 欧美午夜精品久久久久久久| 欧美日韩激情美女| 亚洲xxxx3d| 国产精品劲爆视频| 一区二区三区动漫| 欧美激情第99页| 日本三级韩国三级久久| 秋霞午夜一区二区| 中文字幕一精品亚洲无线一区| 国产精品一区久久久| 久久精品国产v日韩v亚洲| 91成人在线播放| 成人网在线视频| 国产精品视频中文字幕91| 国产精品成人播放| 亚洲老头老太hd| 91精品视频一区| 91老司机精品视频| 久久精品中文字幕免费mv| 日韩在线观看免费高清| 中日韩美女免费视频网址在线观看| 福利二区91精品bt7086| 国产一区二区动漫| 色偷偷偷综合中文字幕;dd| 最近2019好看的中文字幕免费| 欧美精品videossex88| 国产91成人video| 国产精品自产拍在线观| 国产精品第三页| 国产成人精品一区二区在线| 欧美日韩在线观看视频| 8090理伦午夜在线电影| 一区二区国产精品视频| 日本中文字幕不卡免费| 成人免费午夜电影| 国产原创欧美精品| 91精品国产自产在线| 亚洲人精选亚洲人成在线| 国产精品入口夜色视频大尺度| 欧美大成色www永久网站婷| 中文字幕av一区二区| 午夜精品一区二区三区在线视| 国产精品91久久| 欧美自拍大量在线观看| 欧美日本高清视频| 在线视频中文亚洲| 成人看片人aa| 成人高清视频观看www| 中文字幕少妇一区二区三区| 日韩国产精品亚洲а∨天堂免| 国产自产女人91一区在线观看| 久久精视频免费在线久久完整在线看| 午夜精品久久久99热福利| 亚洲国产精品久久久久秋霞蜜臀| 亚洲欧美综合图区| 中文字幕久热精品在线视频| 国产成人精品国内自产拍免费看| 色综合久久88| 91亚洲精品一区二区| 日韩av在线看| 色偷偷av一区二区三区| 精品日本美女福利在线观看| 91免费欧美精品| 成人免费直播live| 日韩中文字幕亚洲| 欧美一区二区.| 亚洲精品电影网站| 亚洲成人a**站| 亚洲直播在线一区| 国内揄拍国内精品少妇国语| 欧美日韩美女在线观看| 亚洲美女黄色片| 日韩欧美国产黄色| 高清欧美性猛交xxxx| 国产99久久精品一区二区 夜夜躁日日躁| 国内精品视频久久| 日韩视频在线一区| 国产精品扒开腿做爽爽爽男男| 欧美一级电影在线| 欧美国产视频日韩| 国产精品老牛影院在线观看| 国产精品夜间视频香蕉| 精品福利免费观看| 亚洲欧美日韩综合| 日韩欧亚中文在线| 国产aⅴ夜夜欢一区二区三区| 欧美色图在线视频| 亚洲综合日韩中文字幕v在线| 欧美激情精品久久久久久大尺度| 日韩精品视频免费在线观看| 久久亚洲精品中文字幕冲田杏梨| 久久艳片www.17c.com| 亚洲伊人久久综合| 国产成人精品一区二区| 欧美日韩国产成人高清视频| 亚洲精品丝袜日韩| 国内精品久久久久影院优| 国产精品视频99| 欧美日韩不卡合集视频| 欧美精品在线免费| 91久久精品一区| 欧美极品第一页| 久久中文字幕视频| 日韩在线播放视频| 欧美猛男性生活免费| 影音先锋欧美在线资源| 亚洲毛片在线观看.| 久久久视频免费观看| 精品日本高清在线播放| 中文字幕日韩欧美精品在线观看| 日韩精品日韩在线观看| 欧美黄色成人网| 久久久精品久久| 亚洲精品国产成人| 欧美日韩在线观看视频| 欧美另类精品xxxx孕妇| 91精品视频一区| 最近2019中文字幕第三页视频| 欧美中文字幕在线播放| 91高潮在线观看| 欧美多人爱爱视频网站| 国内精品国产三级国产在线专| 91视频国产精品| 亚洲精品国精品久久99热一| 国产精品麻豆va在线播放| 国产亚洲欧洲高清| 91精品国产高清久久久久久91| 亚洲aⅴ男人的天堂在线观看| 久久亚洲精品毛片| 欧美日韩精品在线视频| 亚洲国产另类 国产精品国产免费| 亚洲天堂视频在线观看| 国产成一区二区| 最好看的2019的中文字幕视频| 欧美激情网站在线观看| 欧美精品少妇videofree| 性视频1819p久久| 亚洲第一区在线| 久久人人爽人人| 欧美日韩成人免费| 久久久免费av| 亚洲自拍偷拍一区| 亚洲精品久久久一区二区三区| 成人网中文字幕| 国产欧美日韩高清| 成人免费视频97| 欧美视频免费在线观看| 国产精品久久久999| 日韩中文字在线| 国产精品1区2区在线观看| 欧美极品美女视频网站在线观看免费| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲free性xxxx护士hd| 日韩电影免费在线观看中文字幕| 欧美激情a在线| 一区二区在线视频播放| 欧美劲爆第一页|