作者热门文章
- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
当我尝试以 pointfree 风格编写 JavaScript 时,我发现如果强制每个函数都采用这种风格,有时会失去其可读性。例如:
import R from 'ramda'
const ceil = Math.ceil
const pagination = {
total: 101,
itemsPerPage: 10,
currentPage: 1
}
// ================= Pointful style ==================
const pageCount = (pagination) => {
const pages = ceil(pagination.total / pagination.itemsPerPage)
const remainPages = pagination.total % pagination.itemsPerPage === 0 ? 0 : 1
return pages + remainPages
}
pageCount(pagination) // => 11
// ================ Pointfree style ==================
const getPages = R.pipe(
R.converge(R.divide, [R.prop('total'), R.prop('itemsPerPage')]),
ceil
)
const getRemainPages = R.ifElse(
R.pipe(
R.converge(R.modulo, [R.prop('total'), R.prop('itemsPerPage')]),
R.equals(0)
),
R.always(0),
R.always(1)
)
const pageCount2 = R.converge(R.add, [
getPages,
getRemainPages
])
pageCount2(pagination) // => 11
我编写了一个简单的分页模块来计算 pageCount
,以 pointful 样式和 pointfree 样式给出总项目数和每页项目数。显然,pointful 样式比 pointfree 样式版本更具可读性。后者有点晦涩。
我做的对吗?有什么方法可以使 pointfree 风格的代码更具可读性吗?
最佳答案
让我们从手动组合函数开始:
const calcPages = (totalItems, itemsPerPage) =>
ceil(div(totalItems, itemsPerPage));
const div = (x, y) => x / y;
const ceil = Math.ceil;
const pagination = {
total: 101,
itemsPerPage: 10,
currentPage: 1
}
console.log(
calcPages(pagination.total, pagination.itemsPerPage)
);
下一步我们将参数抽象出来:
const comp2 = (f, g) => (x, y) => f(g(x, y));
const div = (x, y) => x / y;
const ceil = Math.ceil;
const calcPages = comp2(ceil, div);
const pagination = {
total: 101,
itemsPerPage: 10,
currentPage: 1
}
console.log(
calcPages(pagination.total, pagination.itemsPerPage)
);
函数定义现在是无点的。但是调用代码不是。如果您知道高阶函数 comp2
的工作原理,表达式 comp2(ceil, div)
对您来说就非常具有声明性。
现在很明显,calcPages
是错误的名称,因为函数组合更为通用。我们称它为 ... intDiv
(好吧,可能有更好的名字,但我的数学很烂)。
下一步我们修改intDiv
,让它可以处理对象:
const destruct2 = (x, y) => f => ({[x]:a, [y]:b}) => f(a, b);
const comp2 = (f, g) => (x, y) => f(g(x, y));
const div = (x, y) => x / y;
const ceil = Math.ceil;
const intDiv = comp2(ceil, div);
const calcPages = destruct2("total", "itemsPerPage") (intDiv);
const pagination = {
total: 101,
itemsPerPage: 10,
currentPage: 1
}
console.log(
calcPages(pagination)
);
我再次调用修改后的函数 calcPages
,因为它现在需要一个特定的 pagination
对象,因此不太通用。
如果您知道所涉及的高阶函数是如何工作的,那么一切都是声明式的并且可读性很好,即使它是以无点风格编写的。
无点风格是函数组合、柯里化(Currying)和高阶函数的结果。它本身不是一个东西。如果您停止使用这些工具以避免无点风格,那么您将失去函数式编程提供的许多表现力和优雅。
关于javascript - 如何在 JavaScript 中使用 pointfree 风格而不失可读性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42068296/
我是一名优秀的程序员,十分优秀!