【发布时间】:2018-12-26 16:55:26
【问题描述】:
考虑take的以下实现:
const take = (n, [x, ...xs]) =>
n === 0 || x === undefined ?
[] : [x, ...take(n - 1, xs)];
console.log(take(7, [1, 2, 3, 4, 5])); // [1, 2, 3, 4, 5]
console.log(take(3, [1, 2, 3, 4, 5])); // [1, 2, 3]
console.log(take(1, [undefined, 1])); // []
如您所见,它不适用于带有undefined 的数组,因为x === undefined 不是测试数组是否为空的最佳方法。下面的代码解决了这个问题:
const take = (n, xs) =>
n === 0 || xs.length === 0 ?
[] : [xs[0], ...take(n - 1, xs.slice(1))];
console.log(take(7, [1, 2, 3, 4, 5])); // [1, 2, 3, 4, 5]
console.log(take(3, [1, 2, 3, 4, 5])); // [1, 2, 3]
console.log(take(1, [undefined, 1])); // [undefined]
但是,编写 xs[0] 和 xs.slice(1) 并不优雅。此外,如果您需要多次使用它们也是有问题的。您要么必须复制代码并做不必要的额外工作,要么必须创建块作用域、定义常量并使用 return 关键字。
最好的解决方案是使用let expression。不幸的是,JavaScript 没有它们。那么,如何在 JavaScript 中模拟 let 表达式呢?
【问题讨论】:
-
undefined是一个真实值,但不是稀疏数组的一部分。一个真正的稀疏数组看起来像[, 1]。 -
@NinaScholz 啊,我明白了。我的印象是
[, 1]和[undefined, 1]是等价的,但显然并非如此。谢谢你告诉我。 -
使用
slice的数组take函数肯定很奇怪,是的:-) -
为什么不简单地
const take = (n, xs) => xs.slice(0, n)? -
@AramilRey 因为那是我为这个问题编造的一个例子。
标签: javascript ecmascript-6 functional-programming let