数学中的函数是什么?
y = f(x)
从上面的例子可以看出:
- 函数必须总是接收一个参数
- 函数必须总返回一个值
- 函数应该依据接收到的参数(例如X)而不是外部环境运行
- 对于一个给定的X,只会输出唯一的一个Y
接下来让我们来看一个计税函数的例子:
let percentValue = 5;
const calculateTax = (value)=> value/100 * (100 + percentValue);
从数学函数的定义上面的calculateTax
函数不能称为一个真正意义上的函数;但我们对它稍加改动,便能让它成为一真正意义上的函数
const calculateTax = (value,percentValue)=> value/100 * (100 + percentValue);
函数式编程主要是基于数学函数和它的思想,它是一种范式(范式是什么请大家自行理解),我们能够以此创建仅依赖于输入就可以完成自身逻辑的函数
引用透明性
根据数据函数的定义:我们可以得出一个结论:所有的函数对于相同的输入,都将返回相同的值,函数的这一属性被称为引用透明性
举个例子:
const identity = i => i
假设该函数被其他的函数调用:
sum(4,5) + identity(1)
根据引用透明性的定义, 我们可以把上面的语句转换为:
sum(4,5) + 1
该过程被称为 替换模型,因为你可以直接替换函数的结果(主要因为函数的逻辑不依赖于其他的全局变量),这与他的值是一样的。这使并发代码和缓存成为了可能
命令式,声明式,抽象
函数式编程主张声明式编程和编写抽象的代码
让我们看一个例子,用命令式方法遍历一个数组:
const array = [1,2,3];
for(let i = 0; i < array.length; i++)
console.log(array[i]); //打印1,2,3
从这段代码可以看出:我们在告诉程序,我们要 如何
做,首先我们告诉编辑器我们要获取数组长度,然后循环数组,用索引获取每一个数组元素,然后打印还数组元素等等,我们将之称为命令式
解决方案, 命令式编程
主张告诉编译器 如何做
让我再接着看另一个例子
const array = [1,2,3];
array.foreach(element => console.log(element)); //打印1,2,3
从上面的代码可以看出,这段代码没有在告诉编译器如何做,而是在让开发者只需要关心做什么
, 这个非常重要。
函数式编程主张以抽象的方法创建函数,这些函数能够在代码的其他部分被重用
纯函数
纯函数是对给定的输入返回相同的输出的函数, 纯函数遵守引用透明性
const double = value => value * 2;
函数式编程的好处
- 易于测试
- 并发执行
- 可缓存
函数式编程在Javascript中的应用
问题: Javascript是函数式编程语言吗?
答案是不是,让我们来看一个例子:
const uselessFunc = () => {}
因为函数式编程语言主张函数必须接受一个或多个参数并且返回一个值,但Javascript非常适合函数式编程范式,因为Javascript语言支持将函数作为参数,传递给另一个函数(当一门语言允许函数作为任何其他任何数据类型使用时,函数被称为一等公民)
高阶函数(Higher-Order Function)
接受一个函数或多个函数作为其参数的函数或者返回值是函数的函数叫做高阶函数
让我们来看一个数学例子:
function add(x, y, f) {
return f(x) + f(y);
}
让我们来看一个简单的例子:
const every. = (arr, fn) => {
let result = true;
for(let i = 0; i< arr.length; i++)
result = result && fn(arr[i])
return result;
}
every([NaN,NaN,NaN], isNaN)
=> true
every([NaN,NaN, 4], isNaN);
=> false
让我们再来看一个例子:
const foreach = (arr, fn) => {
for(let i = 0; i < arr.length; i++){
fn(arr[i]);
}
}
foreach([1,2,3], (i)=> console.log(i));
//打印1,2,3
从上面的两个例子可以看出: 高阶函数本身其实是一种抽象,抽象让我们专注于我们需要做什么,而无须关心底层的概念和实现
函数式编程在数组中的应用
- map 函数
const map= (array, fn) => {
let result = [];
for(const value of array)
result.push(fn(value));
}
return result;
map([1,2,3], x => x * x); => [1,4,9];
- filter函数
const filter = (array, fn) => {
let result = [];
for(const value of array){
fn(value) ? result.push(value): undefind
}
}
filter([1,2,3,4,5], (i) => i % 2 === 0); => [2,4]
柯里化
例子:
const add = (x,y) => x + y;
const addCurried = x = > y => x + y;
addCurried(4);
addCurried(4)(4)
=> 8
柯里化是一个把多参数函数转化为一个嵌套的一元函数的过程
React-Redux,
为什么要进行柯里化, 有什么好处? :)
消参数?