可能你會很熟練,但名稱不一定知道。
今日早讀文章由@reahink翻譯授權分享。
正文從這開始~~
讓我們談談什麼是:lambdas(匿名函數)、 first-class functions(頭等函數)、higher-order functions(高階函數)、unary functions(一元函數)、currying(柯裡化 )和pure functions(純函數)。
如果您不清楚命令式和聲明式編程之間的區別,可以看我的文章: Imperative versus declarative code… what’s the difference?
Lambdas (λ) 在 JavaScript 作為arrow functions(箭頭函數)被廣為所知:
// this is your regular named function in JavaScript
function namedFunction (a, b) {
return a + b;
}
// this is a lambda, i.e. an arrow function
const lambda = (a, b) => a + b;
術語lambda是一個正式的數學邏輯系統,起源於lambda演算。
Lambda演算是由圖靈完成的,它代表了能夠構建任何圖靈機的通用計算模型。
Lambda expressions(匿名函數表達式) 是函數式編程的基石。
如果它對你有所幫助,只需將它視為函數的新縮短語法就行。
然而,在對象或類中使用它們時要注意this的指向。
什麼是first-class functions(頭等函數)?First-class type 意味著,該類型可以用作變量的值。
在JavaScript中一個字符串是頭等類型,一個函數也是頭等類型。
所以函數可以接受其他函數作為參數,並返回函數作為返回值。
在綁定事件監聽器時,函數作為first-class被使用:
const handler = () => console.log ('I am function');
document.addEventListener ('click', handler);
高階函數是一個接受其他函數作為參數或將函數作為返回值返回的函數。
First-order function(一階函數)是一個函數,它不接受其他函數作為參數,並且不返回函數作為其返回值。
const firstOrder = () => console.log ('First order strikes back!');
const higherOrder = whoStrikesBack => whoStrikesBack ();
higherOrder (firstOrder);
該術語涉及一個函數接受一些參數的元數。
一元函數(i.e. monadic)是一個只接受一個參數的函數。
const unaryFunction = message => console.log (message);
const binaryFunction = (color, message) =>
console.log (`%c${message}`, `color:${color}`);
const ternaryFunction = (fnc, color, message) =>
fnc (`%c${message}`, `color:${color}`);
Currying(柯裡化)是一個帶有多個參數的函數並將其轉換為函數序列的過程,每個函數只有一個參數。
一個有n個參數的函數,可以使用柯裡化將它變成一個一元函數。
const binaryFunction = (a, b) => a + b;
const curryUnaryFunction = a => b => a + b;
curryUnaryFunction (1); // returns a function: b => 1 + b
curryUnaryFunction (1) (2); // returns the number 3
Currying(柯裡化)以數學家 Haskell Curry的名字命名,不是吃的。
柯裡化函數非常適合提高代碼的可重用性和函數式結構。
想了解更多,請參考: JavaScript ES6 curry functions with practical examples。
它可能會讓人習慣,但是我現在寫的所有函數都歸功於柯裡化。
純函數是一種其返回值僅由其參數決定,沒有任何副作用的函數。
這意味著如果你在整個應用程式中的不同的一百個地放調用一個純函數相同的參數一百次,該函數始終返回相同的值。
純函數不會更改或讀取外部狀態。
let myArray = [];
const impureAddNumber = number => myArray.push (number);
const pureAddNumber = number => anArray =>
anArray.concat ([number]);
console.log (impureAddNumber (2)); // returns 1
console.log (myArray); // returns [2]
console.log (pureAddNumber (3) (myArray)); // returns [2, 3]
console.log (myArray); // returns [2]
myArray = pureAddNumber (3) (myArray);
console.log (myArray); // returns [2, 3]
在數組中,Push函數就是不純的,它會改變它所調用的數組,因此會產生副作用。
push的返回值是一個數字索引。
另外,Concat接受數組並將其與另一個數組連接,從而產生一個沒有副作用的全新數組。
然後返回兩個數組串聯後的新數組。
純函數很重要,因為它們簡化了單元測試(沒有副作用,也不需要依賴注入),它們避免緊密耦合,並通過消除副作用,使應用程式更加簡潔。
我專門撰寫了一篇文章來討論純函數在編程中的最佳實踐:JavaScript Pure Functions for OOP developers(https://medium.com/front-end-weekly/javascript-pure-functions-for-oop-developers-5fc9020541a8)
理解函數式編程並不能讓你成為更好的開發者,它會讓你成為一個更好的人。
你可以通過lambda演算用啤酒來招待你的朋友,可以通過有趣的數學邏輯來糾正你的家人。
譯者:@reahink更多優質前端教程盡在妙味課堂:
https://study.miaov.com/study