摘要
我们常写的一般都是命令式编程,按步骤执行,关心解决问题的步骤, 比如
var a = [1,2,3];
var sum = 0;
for (var i = 0 ; i < a.length; i ++) {
sum += a[i];
}
函数式编程,关心数据的映射 , 是声明式编程,对函子的操作,把命令拆分成粒子化的函子操作, 更多的目标在于提供可复用的工具库,实际使用场景中采用组合工具的方式达到实现场景。
广义上来说,函子是纯函数,输入一定,输出一定,不包含任何对外的触发事件等任何会影响外部数据的事情。
举个例子:
计算1000以内奇数的总和。
// 是否奇数
function isOdd(i) {
return i%2;
}
// 求和
function sum(arr) {
let sum = 0;
arr.filter((i) => {
reutrn isOdd(i)
}).forEach((j) => {
sum += j;
})
return sum;
}
function generate(m) {
let arr = [];
for(var i = 0 ; i < m; i++ ) {
arr.push(i);
}
return arr;
}
sum(generate(1000));
// 使用组合函子
function compose (f, args) {
return f(args);
}
compose(sum, compose(generate, 1000));
常见的函数库
lodash 、 underscore 、 ramda
lodash 的 curry
函数柯里化是指,把接受多个参数的函数转换成接受一个单一参数的函数
var add = function(a, b) {
return a + b;
}
var add1 = _.curry(add(2));
add1(3); // 返回5
但实际上,完全可以用es6 代替
var add = a => b => a+b;
add1 = add(2);
add1(3); // 返回5
const [last, ...initial] = [1,2,3].reverse(); // last 3 initial [2, 1]
与数学的关系
唉,不知道为啥一定要扯上数学里面范畴学这些高深莫测的专业术语,用简单的方式去理解去解释不好嘛...喵了个咪
链式函数
相比嵌套的函数式编程,链式会更加清晰。
var f = function (i) {
this.arr = [];
this.generate = function (m) {
for(var i = 0 ; i < m; i++ ) {
this.arr.push(i);
}
}
this.sum = function() {
let _this = this;
let sum = 0;
this.arr.filter((i) => {
reutrn _this.isOdd(i)
}).forEach((j) => {
sum += j;
})
return sum;
}
this.isOdd = function(i) {
return i%2;
}
}
f.generate(1000).sum();
jquery 就是非常明显的链式函数编程。
$.getJSON(url, () => {
}).then(() => {
});