写作不易,Star是最大鼓励,感觉写的不错的可以给个Star⭐,请多多指教。本博客的Github地址。
什么是函数式编程
函数式是一种编程形式,我们可以将函数作为参数传递给其他函数,也可以将函数作为返回值返回,还可以在将函数作为参数的同时,再将函数作为返回值返回。 在函数式编程中,我们以函数的形式思考和编程。
高阶函数
在JS中,函数是一种特殊类型的对象,它们是Function objects。我们可以像给对象添加属性一样给函数添加属性,但是不推荐这样做。 高阶函数是对其他函数进行操作的函数,操作可以是将它们作为参数,或者是返回它们。 简单来说,满足以下任何一点的都属于高阶函数:
- 接受一个或多个函数作为参数;
- 返回一个函数。
在js中内置了一些高阶函数,比如数组的map、forEach、reduce等。
函数作为参数传递
Array.prototype.map
举个🌰:现有一个数组[1, 2, 3],我们想要基于该数组来生成一个新数组,其新数组中每个元素都是之前数组的两倍,分别使用高阶和不使用高阶函数的方式来实现。代码如下:
不使用高阶函数:
const arr1 = [1, 2, 3];
const arr2 = [];
for (let i = 0; i < arr1.length; i++) {
arr2.push(arr1[i] * 2);
}
console.log(arr1); // [ 1, 2, 3 ]
console.log(arr2); // [ 2, 4, 6 ]
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
使用map高阶函数:
const arr1 = [1, 2, 3];
const arr2 = arr1.map(item => item * 2);
console.log(arr1); // [ 1, 2, 3 ]
console.log(arr2); // [ 2, 4, 6 ]
1
2
3
4
5
6
2
3
4
5
6
Array.prototype.filter
举个🌰:现在有一个数组[1, 2, 3, 2, 3, 1, 4, 4, 5, 5],我们想要生成一个新数组,这个数组要求没有重复的内容,即为去重。
不使用高阶函数:
const arr = [1, 2, 3, 2, 3, 1, 4, 4, 5, 5];
const arr2 = [];
for (let i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) === i) {
arr2.push(arr[i]);
}
}
console.log(arr); // [ 1, 2, 3, 2, 3, 1, 4, 4, 5, 5 ]
console.log(arr2); // [ 1, 2, 3, 4, 5 ]
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
使用filter高阶函数:
const arr = [1, 2, 3, 2, 3, 1, 4, 4, 5, 5];
const arr2 = arr.filter((item, index, sourceArray) => {
if (sourceArray.indexOf(item) === index) {
return item;
}
});
console.log(arr); // [ 1, 2, 3, 2, 3, 1, 4, 4, 5, 5 ]
console.log(arr2); // [ 1, 2, 3, 4, 5 ]
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
函数作为返回值输出
判断类型函数
const types = ['Number', 'String','Object','Array','Null','Undefined','Boolean'];
const util = {};
const isType = type => obj => Object.prototype.toString.call(obj).includes(type);
types.forEach(type => {
util[`is${type}`] = isType(type);
});
console.log(util.isString('test')); // true
console.log(util.isString(123)); // false
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
add 函数
add(1); // 1
add(1)(2); // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10
// 以此类推
1
2
3
4
5
6
2
3
4
5
6
我们知道打印函数时会自动调用toString()方法,函数add(a)返回一个闭包sum(b),函数sum中累加计算a += b,只需要重写sum.toString()方法返回变量a就可以了。
function add(a) {
function sum(b) {
a += b;
return sum; // 链式调用
}
sum.toString = function() {
return a;
}
return sum;
}
add(1);
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
高阶函数优点
- 使我们的代码更加清晰简洁;
高阶函数实现
举个🌰:假设我们有一个字符串数组,我们希望把它转换为整数数组,其中每个元素代表原始数组中字符串的长度。实现代码如下:
const strArray = ['JavaScript', 'Python', 'PHP', 'Java', 'C'];
Array.prototype.mapForEach = function(cb) {
const arr = this;
const res = [];
if (!Array.isArray(arr)) {
throw new TypeError('type error');
}
for (let i = 0; i < arr.length; i++) {
res.push(cb(arr[i]));
}
return res;
}
const res = strArray.mapForEach(item => item.length);
console.log(res); // [ 10, 6, 3, 4, 1 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17