关于html5:vuereact函数式编程

48次阅读

共计 2637 个字符,预计需要花费 7 分钟才能阅读完成。

函数式编程
JavaScript 语言从一诞生,就具备函数式编程的烙印。它将函数作为一种独立的数据类型,与其余数据类型处于齐全平等的位置。在 JavaScript 语言中,你能够采纳面向对象编程,也能够采纳函数式编程。有人甚至说,JavaScript 是有史以来第一种被大规模采纳的函数式编程语言。

ES6 的种种新增性能,使得函数式编程变得更不便、更弱小。本章介绍 ES6 如何进行函数式编程。

柯里化
柯里化(currying)指的是将一个多参数的函数拆分成一系列函数,每个拆分后的函数都只承受一个参数(unary)。

function add (a, b) {
return a + b;
}

add(1, 1) // 2
复制代码
下面代码中,函数 add 承受两个参数 a 和 b。

柯里化就是将下面的函数拆分成两个函数,每个函数都只承受一个参数。

function add (a) {
return function (b) {

return a + b;

}
}
// 或者采纳箭头函数写法
const add = x => y => x + y;

const f = add(1);
f(1) // 2
复制代码
下面代码中,函数 add 只承受一个参数 a,返回一个函数 f。函数 f 也只承受一个参数 b。

函数合成
函数合成(function composition)指的是,将多个函数合成一个函数。

const compose = f => g => x => f(g(x));

const f = compose (x => x * 4) (x => x + 3);
f(2) // 20
复制代码
下面代码中,compose 就是一个函数合成器,用于将两个函数合成一个函数。

能够发现,柯里化与函数合成有着亲密的分割。前者用于将一个函数拆成多个函数,后者用于将多个函数合并成一个函数。

参数倒置
参数倒置(flip)指的是扭转函数前两个参数的程序。

var divide = (a, b) => a / b;
var flip = f.flip(divide);

flip(10, 5) // 0.5
flip(1, 10) // 10

var three = (a, b, c) => [a, b, c];
var flip = f.flip(three);
flip(1, 2, 3); // => [2, 1, 3]
复制代码
下面代码中,前端培训如果依照失常的参数程序,10 除以 5 等于 2。然而,参数倒置当前失去的新函数,后果就是 5 除以 10,后果失去 0.5。如果原函数有 3 个参数,则只颠倒前两个参数的地位。

参数倒置的代码非常简单。

let f = {};
f.flip =
fn =>

(a, b, ...args) => fn(b, a, ...args.reverse());

复制代码
执行边界
执行边界(until)指的是函数执行到满足条件为止。

let condition = x => x > 100;
let inc = x => x + 1;
let until = f.until(condition, inc);

until(0) // 101

condition = x => x === 5;
until = f.until(condition, inc);

until(3) // 5

下面代码中,第一段的条件是执行到 x 大于 100 为止,所以 x 初值为 0 时,会始终执行到 101。第二段的条件是执行到等于 5 为止,所以 x 最初的值是 5。

执行边界的实现如下。

let f = {};
f.until = (condition, f) =>
(…args) => {

var r = f.apply(null, args);
return condition(r) ? r : f.until(condition, f)(r);

};

下面代码的要害就是,如果满足条件就返回后果,否则一直递归执行。

队列操作
队列(list)操作包含以下几种。

head:取出队列的第一个非空成员。
last:取出无限队列的最初一个非空成员。
tail:取出除了“队列头”以外的其余非空成员。
init:取出除了“队列尾”以外的其余非空成员。
上面是例子。

f.head(5, 27, 3, 1) // 5
f.last(5, 27, 3, 1) // 1
f.tail(5, 27, 3, 1) // [27, 3, 1]
f.init(5, 27, 3, 1) // [5, 27, 3]
复制代码
这些办法的实现如下。

let f = {};
f.head = (…xs) => xs[0];
f.last = (…xs) => xs.slice(-1);
f.tail = (…xs) => Array.prototype.slice.call(xs, 1);
f.init = (…xs) => xs.slice(0, -1);
复制代码
合并操作
合并操作分为 concat 和 concatMap 两种。前者就是将多个数组合成一个,后者则是先解决一下参数,而后再将处理结果合成一个数组。

f.concat([5], [27], [3]) // [5, 27, 3]
f.concatMap(x => ‘hi ‘ + x, 1, [[2]], 3) // [‘hi 1’, ‘hi 2’, ‘hi 3’]
复制代码
这两种办法的实现代码如下。

let f = {};
f.concat =
(…xs) => xs.reduce((a, b) => a.concat(b));
f.concatMap =
(f, …xs) => f.concat(xs.map(f));
复制代码
配对操作
配对操作分为 zip 和 zipWith 两种办法。zip 操作将两个队列的成员,一一配对,合成一个新的队列。如果两个队列不等长,较长的那个队列多进去的成员,会被疏忽。zipWith 操作的第一个参数是一个函数,而后会将前面的队列成员一一配对,输出该函数,返回值就组成一个新的队列。

上面是例子。

let a = [0, 1, 2];
let b = [3, 4, 5];
let c = [6, 7, 8];

f.zip(a, b) // [[0, 3], [1, 4], [2, 5]]
f.zipWith((a, b) => a + b, a, b, c) // [9, 12, 15]
复制代码
下面代码中,zipWith 办法的第一个参数是一个求和函数,它将前面三个队列的成员,一一配对进行相加。

这两个办法的实现如下。

let f = {};

f.zip = (…xs) => {
let r = [];
let nple = [];
let length = Math.min.apply(null, xs.map(x => x.length));

for (var i = 0; i < length; i++) {

xs.forEach(x => nple.push(x[i])
);

r.push(nple);
nple = [];

}

return r;
};

f.zipWith = (op, …xs) =>
f.zip.apply(null, xs).map(

(x) => x.reduce(op)

);

正文完
 0