前言
何为加法?自然是两数相加,但是今天我要讲点不一样的加法,由浅入深,从普通加法到科里化加法,不断升级加法的形态,从无垢巨人的初级形态,成为进击的巨人吧!!
正文
无垢的加法
欢迎来到无垢的世界!
说到加法第一想到的那肯定是a+b=c,于是我们就有了以下代码
function add(a, b){
return a + b;
}
但是这要写未免简陋了点,这里面还是有一些小小问题的,万一输入的参数不够呢?万一数据类型有问题呢?于是就有了
function add(a, b){
// 参数数量问题
if(arguments.length !== 2){
console.log('参数数量错误');
return;
}
// 数据类型问题
if(typeof a !== 'number' || typeof b !== 'number'){
console.log('类型错误');
return;
}
return a + b;
}
现在就优雅许多了,当我们到达这个最初级的加法形式,我们就已经成为了初级的小无垢了
可是如果我们一次给的参数不够只能一次给一部分怎么办?或者说我想可以三个、四个、甚至更多数相加呢?没办法,目前的你是实现不了的,毕竟你现在只是个小小无垢,这对于你来说还是太困难了,看来我们得继续升级了。
这个时候就出现了新写法-闭包,无垢加点脑
进击的加法
给我们的小无垢加点脑后,终于我们来到了智慧巨人的世界
现在我们要去实现无垢无法实现的问题了
这也便是柯里化的思想,把一个多参数的函数逐步拆分成多个单参数的函数组合
实现这个的话我们要使用闭包
什么是闭包呢?
闭包是一个函数,这个函数能够访问并记住它周围环境(包括外部函数)的变量,即使这个外部函数已经执行完毕。闭包"闭合"了函数内部和外部的变量作用域。
文字可能有点抽象,那我们直接上代码
function outerFunction() {
let count = 0;
function innerFunction() {
count++;
console.log("Count is:", count);
}
return innerFunction;
}
const myFunction = outerFunction();
myFunction(); // Count: 1
myFunction(); // Count: 2
myFunction(); // Count: 3
相信通过这段代码大家一定懂了什么是闭包了吧,那么我们的加法就开始进行升级了
- 实现可以三个、四个、甚至更多数相加
function add(x) {
return function (y) {
return x + y;
}
}
console.log(add(1)(2)); // 3
console.log(add(1)(2)(3)); // 6
console.log(add(1)(2)(3)(4)); // 10
add函数接受一个参数x,并返回一个新的函数。- 返回的这个新函数也接受一个参数
y,并返回x + y的结果。 - 当我们调用
add(1)时,它会返回一个新的函数。这个新函数"记住"了x的值为1。 - 当我们继续调用返回的函数,比如
add(1)(2),它会把y的值设置为2,并返回x + y,也就是1 + 2 = 3。 - 同理,
add(1)(2)(3)会返回1 + 2 + 3 = 6,add(1)(2)(3)(4)会返回1 + 2 + 3 + 4 = 10。
这样的写法可以实现多个数不断相加
- 实现将函数参数分批给
const curry = (fn, ...args) =>
// console.log(args.length, fn.length);
args.length >= fn.length ? fn(...args):(..._args) => curry(fn, ...args, ..._args)
// 原函数
// 柯里化,慢慢收集
const add = (x, y, z, m) =>{
return x + y + z + m
}
const curryAdd = curry(add,1)
const curryAdd1 = curryAdd(2)
const curryAdd2 = curryAdd1(3)
console.log(curryAdd2(4)); // 10
console.log(curry(add,1)(2)(3)(3)); // 9
-
curry函数接受两个参数:fn: 需要柯里化的原函数...args: 传递给fn的初始参数列表
-
在
curry函数内部,我们首先检查当前传递的参数args是否已经足够调用原函数fn。- 如果参数足够,我们就直接调用
fn并返回结果。 - 如果参数不够,我们返回一个新的函数,该函数会递归调用
curry,并将当前参数和新传入的参数合并起来。
- 如果参数足够,我们就直接调用
经过升级,终于我们成功成为了一个合格的进击巨人!!!
总结
本文深入探讨了 JavaScript 中闭包和函数柯里化的概念及其应用,为读者提供了实践和理解这些重要编程技巧基础。让一个小无垢最终成为了进击巨人