JavaScript 中的函数柯里化
前言
JavaScript 中的柯里化
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
前言
我非常喜欢函数式编程。我当然算不上专家,但我会抓住一切机会提升自己的学习水平,并将函数式编程的理念和实践应用到我自己的编码和设计中。
JavaScript 中的柯里化
我的日常工作是网页开发,主要使用 Rails 和各种前端 JavaScript 框架及库。幸运的是,JavaScript 拥有许多特性,使我能够以函数式编程的方式进行开发。
一阶和高阶函数
要成为函数式语言,其主要特性之一是支持一等函数。也就是说,该语言必须将函数视为一种数据类型,可以像其他任何数据类型一样赋值给变量。高阶函数与一等函数密不可分。高阶函数是指可以接受函数作为参数或返回函数作为值的函数。
柯里化函数
柯里化函数是将一个具有多个参数的函数分解成一系列每个只接受一个参数的函数的过程。
一个简单的例子是sum这样的函数
const sum = function(a, b) {
return a + b;
}
为了对这个sum函数进行柯里化,我们需要让它像一系列单参数函数一样运行。由于函数在 JavaScript 中是一等公民,我们可以让柯里化的求和函数接受一个参数,并返回另一个单参数函数,该函数将其参数加到第一个(外部)函数的参数上。代码如下:
const sum = function(a) {
return function(b) {
return a + b;
};
}
我们可以使用 ES6 箭头函数更简洁地编写这段代码,如下所示。
const sum = (a) => (b) => a + b;
这可以称之为略显怪异的外观
sum(3)(2) // 5
显然,这本身并不能给我们带来任何好处。柯里化的一个更实际的用途是,当你需要对多个输入重复执行相同类型的操作时。这在使用谓词函数时尤其有用。下面我们用老朋友FizzBuzz 2来举例说明。
let isDivisibleBy = (a) => (b) => b % a === 0;
let isFizz = isDivisibleBy(3);
let isBuzz = isDivisibleBy(5);
for(let number in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]) {
if (isFizz(number) && isBuzz(number))
console.log('Fizz Buzz');
else if(isFizz(number))
console.log('Fizz');
else if (isBuzz(number))
console.log('Buzz');
else
console.log(number);
}
这isDivisibleBy是我们的柯里化函数。对于FizzBuzz,我们希望应用一个常见的操作——整除性检查,并处理多个参数,例如 3 和 5。通过柯里化,我们可以将其组合isDivisibleBy成两个更具体的谓词isFizz。isBuzz
我个人觉得这种 if/else 语句比这样说要易读得多。
if (number % 5 === 0 && number % 3 === 0)
console.log('Fizz Buzz');
// ...etc.
关于柯里化及其在 JavaScript 中的应用,当然还有更多更好的内容可以探讨,但我希望这篇文章能对这个概念起到有用的介绍作用。
欢迎提出任何意见和改进建议。
脚注
文章来源:https://dev.to/ludamillion/function-currying-in-javascript-4e8i