高阶函数——优雅的封装

高阶函数

抽象、重复的抽象、可组合性

抽象

看下面的代码,我们将代码封装成函数,它的好处是什么呢?

let total = 0, count = 1;
while(count <= 10) {
	total += count;
  count = 1;
}
console.log(total)

上面是一个简单的累加代码,命令式的编写代码,再简单逻辑的时候我们能够很清楚在干什么,但是一旦变量增多,代码行增加,逻辑复杂起来,我们就很难一下子明白这段代码是在干什么。

console.log(sum(range(1, 10)))

如果我们用两个函数来完成我们的任务,只需要一行代码并且很清楚我们是在求1-10的和。并且下次我们仍然可以复用sumrange函数。sumrange这两个函数定义的操作当然会包含循环、计数和其他一些操作。但相比于将这些代码直接写到一起,这种表述方式更为简单,同时也易于避免错误。

那我们是如何将上面的命令式代码抽象出函数的呢?

任务1:计算1-10的和

  • 需要一个计算和的函数 - 目标求和
function sum(start, end) {
  let total = 0
  for(; start <= end; start++) {
    total += start
  }
  return total;
}

OK,非常完美,而且一个函数就搞定了。而且还能通过参数控制求和范围,具有可扩展性,复用性。

嗯,这确实做到了抽象…

重复的抽象

任务2:现在需要重复十次打印console.log()

function repeat(n) {
  for(let i = 0; i < n; i++ ) {
    console.log(...)
  }
}
repeat(10);

任务3:现在我需要重复十次请求网络资源

function repeatFetch(n) {
  for(let i = 0; i < n; i++ ) {
    fetch(url, options).then(...)
  }
}

现在一看我们封装的函数好像并不够抽象。

我们一直注意次数,却忽略了重复的事情。

再次抽象:我们需要重复的函数,只完成重复n次而不需要关系重复的事情。

function repeat(n, action) {
   for(let i = 0; i < n; i++ ) {
    action(i)
  }
}
repeat(3, console.log)

Perfact!

这样一来,我们就不需要写一堆repeat*的函数了。

优雅的使用:

let labels = [];
repeat(5, i => {
  labels.push(`chapter ${i + 1}`);
});
console.log(labels);
// → ["chapter 1", "chapter 2", "chapter 3", "chapter 4", "chapter 5"]

可组合性

将最基础的函数抽象,让其他函数作为插件使用,扩展我们的基础函数的功能,极大的增强了我们函数的扩展性。

function noisy(f) {
  return (...args) => {
    console.log("calling with", args);
    let result = f(...args);
    console.log("called with", args, ", returned", result);
    return result;
  };
}
noisy(Math.min)(3, 2, 1);
// → calling with [3, 2, 1]
// → called with [3, 2, 1] , returned 1

这种思想在非常多的地方体现,无论是我们使用的框架、打包工具等等。

高阶函数、函数柯里化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值