marp | theme | paginate | header |
---|---|---|---|
true |
uncover |
true |
函数式编程指南 第2章:一等公民的函数 |
第 2 章
《函数式编程指南》
"一等公民"函数和其他数据类型一样
- 存在数组里
- 当作参数传递
- 赋值给变量...
这是 JavaScript 语言的基础概念 但是... 很多人对这个概念的集体无视
// 太傻了
const getServerStuff = (callback) => ajaxCall((json) => callback(json));
// 这才像样
const getServerStuff = ajaxCall;
// 这行
ajaxCall(json => callback(json));
// 等价于这行
ajaxCall(callback);
基于上面,可以重构下
// 那么,重构前
const getServerStuff = (callback) => ajaxCall(callback);
// ...重构后
const getServerStuff = ajaxCall; // 看,没有括号哦
const BlogController = {
index(posts) { return Views.index(posts); },
show(post) { return Views.show(post); },
create(attrs) { return Db.create(attrs); },
update(post, attrs) { return Db.update(post, attrs); },
destroy(post) { return Db.destroy(post); },
};
// 重构后
const BlogController = {
index: Views.index,
show: Views.show,
create: Db.create,
update: Db.update,
destroy: Db.destroy,
}
httpGet('/post/2', (json) => renderPost(json));
// 如果renderPost新增个err参数,那么所有的httpGet都需要跟着改
httpGet('/post/2', (json, err) => renderPost(json, err));
一等公民函数,则少了改动的麻烦
// renderPost参数变化不会影响到httpGet
httpGet('/post/2', renderPost);
// 只针对当前的博客项目
const validArticles = (articles) =>
articles.filter((article) => article !== null && article !== undefined);
// 对未来的项目更友好
const compact = (xs) => xs.filter((x) => x !== null && x !== undefined);
const fs = require('fs');
// 太可怕了
fs.readFile('freaky_friday.txt', Db.save);
// 好一点点
fs.readFile('freaky_friday.txt', Db.save.bind(Db));
一等公民的函数,直接赋值给函数
不要加一层多余的包裹
- 改动更少,参数的变动不会影响到函数的调用
- 使用更通用的命名,对未来的项目更友好