通过实际应用程序理解 JavaScript Currying
您是否在 JavaScript 中见过“柯里化”这个词,并好奇它的含义?在本篇博文中,我们将探讨柯里化的概念,并通过一些简单的例子进行分解,并展示如何在实际场景中使用它,让您的代码更清晰、更灵活。
💡什么是柯里化?
柯里化是一种函数式编程方法,其中函数一次使用一个参数,而不是一次性使用所有参数。柯里化的函数会返回另一个函数,该函数接受下一个参数,直到所有参数都已提供。
简单来说,柯里化将一个包含多个参数的函数转换为一系列函数,每个函数只接受一个参数。
让我们使用现实生活中的类比和代码来理解:
🍔 做汉堡
想象一下在快餐店点一份汉堡。厨师会一层一层地制作你的汉堡:
第一层:面包(第一个参数)。
第二层:肉饼(第二个参数)。
第三层:配料(第三个参数)。
让我们使用常规函数和柯里化函数为上述场景编写代码。📌
使用常规函数:
在常规函数中,所有成分都作为参数一次传递。
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% 的折扣。
现在,让我们先使用常规函数来构建它:
📌 使用常规函数:
使用常规函数进行折扣计算器可能会导致灵活性和代码复用性降低。您必须为每种类型的客户编写单独的函数,或者每次计算折扣时都传递所有参数。
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 函数构建此应用程序:
📌 使用 Curried 函数:
Currying 允许您为各种客户类型创建可重用的函数。您可以为每种消费者类型配置折扣逻辑,而不必不断地提供相同的参数。
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