概念
函数式编程是一种编程范式,我们在其中尝试以纯数学函数风格绑定所有内容。它是一种声明式的编程风格。它的主要重点是“解决什么”,而命令式风格的主要重点是“如何解决”。它使用表达式而不是语句。计算表达式以产生值,而执行语句以分配变量。
函数式编程基于Lambda演算。而且,Lambda演算的函数可以接受函数作为输入参数和输出返回值。
特点
纯函数
这些函数有两个主要属性。首先,它们总是为相同的参数产生相同的输出,而不管其他任何事情。其次,它们没有副作用,即它们不修改任何参数或局部/全局变量或输入/输出流。后来的属性称为不变性。纯函数的唯一结果是它返回的值。它们是确定性的。
let arr = [1, 2, 3, 4, 5];
arr.slice(0, 3); // [1, 2, 3]
arr.slice(0, 3); // [1, 2, 3]
arr.splice(0, 3); // [1, 2, 3]
arr.splice(0, 3); // [4, 5]
// slice会改变参数,而splice会改变,所有slice是纯函数,而splice不是
递归
函数式语言中没有“for”或“while”循环。 函数式语言中的迭代是通过递归实现的。 递归函数反复调用自己,直到达到基本情况。
引用透明
引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。
函数是一等的并且可以是高阶的
一等(first class)函数被视为一等变量。 第一类变量可以作为参数传递给函数,可以从函数返回或存储在数据结构中。 高阶函数是将其他函数作为参数的函数,它们也可以返回函数。
变量是不可变的
在函数式编程中,我们不能在变量初始化后对其进行修改。 我们可以创建新变量——但我们不能修改现有变量,这确实有助于在整个程序运行时维护状态。 一旦我们创建了一个变量并设置了它的值,我们就可以完全确信该变量的值永远不会改变。
高阶函数
在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
- 接受一个或多个函数作为输入
- 输出一个函数
我们说闭包也是高阶函数,因为闭包输出了一个函数,满足高阶函数的第二个条件。
function square(x) {
return x*x;
}
// add接受一个函数为输入,是高阶函数
function add(x, y, fn) {
return fn(x) + fn(y);
}
add(10, -20, square); // 500
函数柯里化
坷里化(Currying)是把接受多个参数的函数变成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
function add(a, b, c) {
return a + b + c;
}
let foo = function(a) {
return function(b) {
return function(c) {
return a + b + c;
}
}
}
foo(1)(2)(3); // 6
// 抽象
function foo(fn, ...args1) {
return function(...args2) {
return function(...arg3) {
return fn(..args1, ...args2, ...args3);
}
}
}
foo(add, 1)(2)(3);
// 自动坷里化
function foo(fn, ...args) {
if (args.length >= fn.length) {
return fn(...args);
}
return function(...args2) {
return foo(fn, ...args, ...args2);
}
}
偏函数
固定某个函数的一个或几个参数,返回一个新的函数,用来接收剩下的参数,这个返回的新函数就是偏函数。
function add(a, b, c) {
return a + b + c;
}
function newAdd = add.bind(null, 1);
newAdd(2, 3); // 6
面试相关
通过更优雅的方式实现纯函数的解耦
let compose = (f, g) => (x => f(g(x)));
let add1 = x => x + 1;
let mul5 = x => x * 5;
compose(mul5, add1)(2); // 15
// 面试题 - 数组长度未知的情况下,拿到最后一项
let first = arr => arr[0];
let reverse = arr => arr.reverse();
let last = compose(first, reverse);
last([1, 2, 3, 4, 5]); // 5
参考文档:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。