您是否在 JavaScript 中看到“柯里化”這個詞並想知道它的含義?在這篇部落格中,我們將研究柯里化的概念,用簡單的範例對其進行分解,並展示如何在現實場景中使用它,以使您的程式碼更清晰、更靈活。
柯里化是一種函數式程式設計方法,其中函數一次使用其每個參數,而不是一次全部使用。柯里化函數傳回另一個接受下一個參數的函數,直到提供所有參數。
簡單來說,柯里化將具有多個參數的函數轉換為一系列函數,每個函數都採用一個參數。
讓我們使用現實生活中的類比和程式碼來理解:
想像一下在速食店點一個漢堡。廚師將逐層準備您的漢堡:
第 1 層:髮髻(第一個參數)。
第 2 層:肉餅(第二個參數)。
第三層:配料(第三個參數)。
讓我們使用正規函數和柯里化函數為上述場景編寫程式碼。
📌 使用常規函數:
在常規函數中,所有成分都作為參數立即傳遞。
function makeBurger(bun, patty, topping) {
return `Your burger has: ${bun} bun, ${patty} patty, and ${topping} topping.`;
}
const myBurger = makeBurger("Sesame", "Mix Veg", "Cheese");
console.log(myBurger); // Output: Your burger has: Sesame bun, Mix Veg patty, and Cheese topping.
📌 使用柯里化函數:
在咖哩函數中,您一次傳遞一種成分。
function makeBurgerCurried(bun) {
return function (patty) {
return function (topping) {
return `Your burger has: ${bun} bun, ${patty} patty, and ${topping} topping.`;
};
};
}
// Example usage
const chooseBun = makeBurgerCurried("Sesame");
const choosePatty = chooseBun("Mix Veg");
const myCurriedBurger = choosePatty("Cheese");
console.log(myCurriedBurger); // Output: Your burger has: Sesame bun, Mix Veg patty, and Cheese topping.
✍️說明:
第一次呼叫: makeBurgerCurried("Sesame")
接收"Sesame"
並傳回一個等待 patty 的新函數。
const chooseBun = makeBurgerCurried("Sesame");
console.log(chooseBun);
/* Output:
ƒ (patty) {
return function (topping) {
return `Your burger has: ${bun} bun, ${patty} patty, and ${topping} topping.`;
};
} */
第二次呼叫: chooseBun("Mix Veg")
接收"Mix Veg"
並傳回另一個等待打頂的函數。
const choosePatty = chooseBun("Mix Veg");
console.log(choosePatty);
/* Output:
ƒ (topping) {
return `Your burger has: ${bun} bun, ${patty} patty, and ${topping} topping.`;
} */
第三次呼叫: choosePatty("Cheese")
接收"Cheese"
並完成函數鏈,返回最終的漢堡描述。
const myCurriedBurger = choosePatty("Cheese");
console.log(myCurriedBurger);
// Output: Your burger has: Sesame bun, Mix Veg patty, and Cheese topping.
您可以使用箭頭函數來簡化柯里化函數:
const curriedArrowFunction = (bun) => (patty) => (topping) =>
`Your burger has: ${bun} bun, ${patty} patty, and ${topping} topping`
const myArrowFunction = curriedArrowFunction("Sesame")("Mix Veg")("Cheese")
console.log(myArrowFunction); // Your burger has: Sesame bun, Mix Veg patty, and Cheese topping
當您需要重複使用具有特定參數的函數時,柯里化尤其方便。它促進程式碼重用、可讀性和模組化。
想像一下您正在開發一個電子商務平台。折扣根據客戶類型計算:
老顧客可享 10% 的折扣。
高級客戶可享 20% 的折扣。
現在讓我們先使用 Regular 函數來建構它:
📌 使用常規函數:
使用折扣計算器的常規函數可能會導致靈活性和可重複使用程式碼的降低。您必須為每種類型的客戶編寫單獨的函數,或在每次計算折扣時傳遞所有參數。
function calculateDiscount(customerType, price) {
if (customerType === "Regular") {
return price * 0.9; // 10% discount
} else if (customerType === "Premium") {
return price * 0.8; // 20% discount
}
}
console.log(calculateDiscount("Regular", 100)); // Output: 90
console.log(calculateDiscount("Premium", 100)); // Output: 80
➖ 正規函數的限制:
重複邏輯:每次都必須傳遞 customerType,即使它在多次計算期間沒有改變。
不可重複使用性:如果您想在多個交易中對一種客戶類型套用折扣,則每次都必須指定該類型。
可擴展性問題:新增額外的客戶類型或折扣規則會使功能變得複雜且更難以維護。
現在讓我們使用 Curried 函數來建立這個應用程式:
📌 使用柯里化函數:
柯里化允許您為各種客戶類型建立可重複使用的函數。您可以為每種消費者類型配置折扣邏輯,而不是不斷給出相同的參數。
function createDiscountCalculator(discountRate) {
return function (price) {
return price * (1 - discountRate);
};
}
// Create specific calculators for different customer types
const regularDiscount = createDiscountCalculator(0.1); // 10% discount
const premiumDiscount = createDiscountCalculator(0.2); // 20% discount
// Use them for calculations
console.log(regularDiscount(100)); // Output: 90
console.log(premiumDiscount(100)); // Output: 80
console.log(regularDiscount(200)); // Output: 180
➕ 柯里化函數的優點:
可重複使用性:一旦指定了regularDiscount
或premiumDiscount
,您將無需在後續交易中再次指定折扣率。
更清晰的程式碼:邏輯是獨立且集中的。每個職能都有一個職責:定義和應用折扣率。
可擴展性:建立新的客戶類型很簡單。例如:
const studentDiscount = createDiscountCalculator(0.15); // 15% discount
console.log(studentDiscount(100)); // 85
regularDiscount
函數指定舊客戶的折扣邏輯。柯里化一開始可能看起來很複雜,但正如我們所看到的,它是一個強大的概念,可以簡化函數建立並使程式碼更清晰、更可重複使用。
現在您已經了解了,請嘗試在您的下一個專案中進行柯里化,然後看看奇蹟發生!
分享你的想法
您在專案中使用過柯里化嗎?您遇到過什麼問題或得到過什麼好處?請在下面的評論中告訴我!
快樂編碼!
原文出處:https://dev.to/thedevricha/understanding-javascript-currying-with-a-real-world-application-51n9