函数式编程的概念
函数式编程是编程范式之一,可以理解为编程风格;思维模式 + 实现方法;常见的编程方式有:
- 面向过程编程:按照步骤实现,一步一步实现功能;
- 面向对象编程:把现实世界中的事物抽象成类和对象,通过封装、继承和多态来演示事物事件的联系;
函数式编程的本质
- 函数式编程中的函数指的不是程序中的函数(方法),而是数学中的函数即映射关系;
- 相同的输入始终得到相同的输出;
- 函数式编程用来描述数据(函数)之间的映射;
// 非函数式
let a = 1;
let b = 1;
let sum = a + b;
console.log(sum)
// 函数式
function add(a, b) {
return a + b;
}
let sum = add(1, 1)
console.log(sum)
函数是一等公民
为什么说函数是一等公民呢,是因为:1. 函数可以存储在变量中;2.函数可以作为参数;3.函数可以作为返回值;
高阶函数
概念:1.可以把函数作为参数传递给另一个函数;2.可以把函数作为另一个函数的返回结果
// 函数作为参数
function forEach(array, fn) {
for (let index = 0; index < array.length; index++) {
fn(array[index])
}
}
// 函数作为返回值
function makeFn() {
let msg = 'hello lsx'
return function() {
console.log(msg);
}
}
makeFn()()
使用高阶函数的意义:
- 可以让函数变得灵活、无需关心内部实现,只需要关注我们的目标;
- 高阶函数是用来抽象通用的问题;
常用的高阶函数:
forEach、map、filter、every、some...
手写实现部分高阶函数
// 实现map循环遍历数据并返回处理过的数组
function map(array, fn) {
let results = []
for(let value of array) {
results.push(fn(value))
}
return results
}
// every判断数组中所有元素是否都满足条件,若有一个不满足条件则返回false,否则返回true
function every(array, fn) {
let result = true
for(let value of array) {
if (!fn(value)) {
result = false
break // break和continue的区别: break跳出整个循环,而continue跳出本次循环
}
}
return result
}
// some数组中只要有一个满足条件即返回true,全不满足返回false
function some(array, fn) {
let result = false
for(let value of array) {
if (fn(value)) {
result = true
break
}
}
return result
}
纯函数
概念:相同的输入永远会得到相同的输出,而且没有任何可观察的副作用,类似于数学中的函数;
// 非纯函数,因为checkAge的min依赖于外部的参数
let min = 18
function checkAge(age) {
return age > min
}
// 纯函数
function checkAge(age) {
let min = 18
return age > min
}
数组中的slice纯函数
splice非纯函数
- slice: 返回数组中的指定部分,不会改变原数组;
- splice: 对数组进行操作返回该数组,会改变原数组; 好处:
- 可缓存;因为相同的输入永远会得到相同的输出,可以把结果缓存起来,lodash里的memoize方法;
- 测试;
- 并行处理;纯函数只依赖于参数,不需要访问共享的内存数据;
对于相同的输入永远会得到相同的输出,而且没有任何可观察的副作用
;副作用会让一个函数变得不纯,纯函数根据相同的输入返回相同的输出,如果函数依赖于外部的状态就无法保证输出相同,就会带来副作用。副作用的来源配置文件、数据库、获取用户的输入...