table of contents

1概述

在之前的文章中,我们学习了许多关于函数本质的知识,那么我们接下来,就应该思考函数的应用问题: 在实际开发中,我们需要用函数来做些什么? 我们可以使用函数这些特性来玩一些什么高级的东西? 我们要如何使用函数才能让我们的代码更加清晰直观?

函数式编程,就是我们接下来要思考的函数应用问题。

2封装

封装是一个非常重要的概念。这个概念在我们的代码中随处可见。

对于函数来说,封装是将一堆代码放在函数中,当我们想要执行这一堆代码的时候,不用重复编写,而只需要调用一下这个函数,就能够做到同样的事情。

因此,将一堆代码封装成为一个函数,会极大的降低我们的代码量。

例如一个简单的例子,我们要计算两个数字的平均值,那么我们会如下计算

code.ts
1
const a = 10
2
const b = 20
3
4
const sum = a + b
5
const average = sum / 2

将其封装成为一个函数之后

code.ts
1
// 封装
2
function getAverage(num1, num2) {
3
const sum = num1 + num2
4
return sum / 2
5
}
6
7
8
// 使用
9
getAverage(10, 20)

当然,如果只是代码的堆砌,封装没有任何难度。而真正需要我们深入思考的核心重点,还在于,要明白,封装,其实是对公共逻辑的提炼。

例如,我们要计算一个数组中,所有子项的和。

如果我们仅仅只是计算一个简单数组的子项之和时,会直接将子项加起来就可以了

code.ts
1
const arr = [1, 2]
2
const sum = arr[0] + arr[1]

但是如果数组的子项数量很多呢?这样的方式就变得非常不合适,因此当我们想要针对所有的数组,来实现计算子项之和时,就必须要提炼出来公共的逻辑。

code.ts
1
// 封装
2
function mergeArr(arr) {
3
const result = 0;
4
for (let i = 0; i++; i < arr.length) {
5
result += arr[i];
6
}
7
8
return result;
9
}
10
11
// 使用
12
mergeArr([1, 2])
13
mergeArr([1, 2, 3, 4, 5])

如果我们在使用函数时,没有去总结过封装的提炼思维,那么你的函数可能会非常糟糕,甚至自缚手脚,出现一些无法预知的 bug。

3函数式编程

函数式编程是一种编程范式,是一个非常好用的封装思维。

现在已知有一个数组,需求是找出数组中的所有数字,并将这些数组放在一个新的数组里。

code.ts
const arr = [1, 3, 'a', 'd', 5, 8, '9']

如果不考虑封装的问题,很容易实现

code.ts
1
const arr = [1, 3, 'a', 'd', 5, 8, '9']
2
const newArr = []
3
4
arr.forEach(item => {
5
if (typeof item === 'number') {
6
newArr.push(item)
7
}
8
})

如果封装只是代码的堆砌,也能够做到

code.ts
1
const arr = [1, 3, 'a', 'd', 5, 8, '9']
2
3
function getNumbers() {
4
const newArr = []
5
6
arr.forEach(item => {
7
if (typeof item === 'number') {
8
newArr.push(item)
9
}
10
})
11
return newArr
12
}
13
14
const newArr = getNumbers()

显然,这并不是很好的方式,这样的方式仅仅只能满足单个数组这样的需求,那如果我们还需要从其他数组中也找出来所有的数字项呢?又只能重新写。

因此,我们要从多个需求场景中,将共同的逻辑提炼出来封装一个函数。

code.ts
1
// 将目标数组作为参数传入到函数中
2
function getNumbers(arr) {
3
const newArr = []
4
5
arr.forEach(item => {
6
if (typeof item === 'number') {
7
newArr.push(item)
8
}
9
})
10
return newArr
11
}
12
13
14
// 使用时
15
const arr = [1, 3, 'a', 'd', 5, 8, '9']
16
const numArr = getNumbers(arr) // 无论有多少个数组,都能够做到同样的需求

封装好之后,我们在使用时,只需要关心该函数有什么功能,需要什么参数,而不需要过多的关心函数的内部实现,就能够顺利的将函数运用起来。从整个项目来说,这样的代码会简洁许多,维护起来也会更加简单。

当然,对于这些简单的案例,许多同学在做封装时,自然的就使用了这样的策略,但是因为没有提炼的意识,在遇到复杂场景时,就容易写出低质量的函数。这里需要我们结合更多的实践,持续的强化我们的提炼思维。

在现实中这种思维也非常常见。

我们点外卖,只需要在 app 中下单,然后等待外卖小哥把外卖送到我们手里就行。我们不用关注我们点的餐是如何做出来的,也不用关注外卖小哥是如何送过来的,这种更加关心结果的思维方式,便是函数式编程的运用。

OK,通过一些简单的案例了解了函数式编程之后,下一章我们将会更加详细的解读函数式编程思维。

专栏首页
到顶
专栏目录