使用 JS 演示一些函数式编程的方法。
pipe
如何使用管道,使一个参数被多个函数依次处理后输出。例子来自 Code with Mosh 的 Redux 课程。
import { pipe } from "lodash/fp";
const pickTag = obj => obj.tag;
const toLowerCase = str => str.toLowerCase();
const bracketify = str => `(${str})`;
const transform = pipe(pickTag, toLowerCase, bracketify);
// output: "(javascript)"
const output = transform({ tag: "JAVASCRIPT" });
Currying
Currying 是一种代码组织方式,用于将一个接受多参数的函数,变成只接受一个参数。通过一个返回函数的函数来实现。函数式编程中一般只接受一个参数。
// Function which takes two argument
function add(a, b) {
return a + b;
}
// Currying: transform into function which takes one argument
function add(a) {
return function(b) {
return a + b;
};
}
const add2 = a => b => a + b; // (a, b) => a + b
add(1)(5); // add(1, 5)
// N => 1
Python 的 functools.partial 也可以用来实现类似的效果。
Tranform immutable data
对于不可变数据结构,如何新增、更新或者删除字段。例子来自 Code with Mosh 的 Redux 课程。JavaScript: Immutable Object 有更多讨论。
变化数组:
const numbers = [1, 2, 3];
// Adding
const index = numbers.indexOf(2);
const added = [...numbers.slice(0, index), 4, ...numbers.slice(index)];
// Removing
const removed = numbers.filter(n => n !== 2);
// Updating
const updated = numbers.map(n => (n === 2 ? 20 : n));
console.log(updated);
变化对象:
const person = {
name: "John",
address: {
country: "USA",
city: "San Francisco"
}
};
const updated = {
...person,
address: {
...person.address,
city: "New York"
},
name: "Bob"
};
console.log(person);
注意,采用 spread operation 时,spread 的语句要写在前面。写在后面的字段有更高的优先级。