假设我有这个简单的JavaScript函数:
function returnArray(){
return [1, 2, 3];
}
进一步假设我说
var test = [0, ...returnArray()];
你希望测试等于[0,1,2,3],你是对的。我试过了,当然有效。
现在我进行了这个练习,我想构建一个名为double的函数,它将一个数组作为参数,并返回另一个包含所有原始数组值的数组。所以,如果我调用double([1,2,3]),我应该得到[2,4,6]。练习的限制是我必须仅使用 数组解构,递归和其余/扩展运算符来构建我的函数。不允许使用数组助手。所以我想出了这个:
function double(array){
if (array.length===1) return 2*array[0];
var [num, ...rest] = array;
if (rest.length!=0) return [2*num, ...double(rest)];
}
如果我使用任何大小至少为2的数组运行此函数,我会收到一条错误消息,指出double不是函数。如果我在double之前删除了...运算符,那么神奇的double再次是一个函数,除了当然double([1,2,3])的结果是[2,[4,6]],这是不完全的与[2,4,6]相同。
我的第一个想法是,由于一些奇怪的原因,你可以在函数前面使用...,即使函数返回一个数组,所以我用returnArray()测试了这个假设功能上面,发现它工作得很好。我不知道它为什么会在练习中崩溃。我只能猜测递归可能与它有关,但我不知道为什么它会如此。任何人都可以指出我的代码出了什么问题吗?
编辑:谢谢大家,这是一个非常愚蠢的错误!我应该看到它。我在你的一些答案中添加了评论。答案 0 :(得分:24)
您的逻辑错误已经在评论和答案中指出,但是让我指出一种更简洁,更容易出错的方法来编写它,这更符合递归的基本原则。
function double([head, ...tail]) {
if (head === undefined) return [];
return [2*head, ...double(tail)];
}
换句话说,只有一个“基本情况”,即空数组,它返回一个空数组。其他一切都是简单的递归。
您可以使用
进一步“功能化”function map(fn) {
return function iter([head, ...tail]) {
return head === undefined ? [] : [fn(head), ...iter(tail)];
};
}
const double = map(x => 2*x);
console.log(double([1, 2, 3]));
答案 1 :(得分:10)
这是一个非常奇怪的错误消息,毫无疑问,但主要问题是double
中的逻辑错误:在代码的两个分支中,调用double
导致不可迭代值(在一种情况下是一个数字,在另一个undefined
中)。但是你总是将扩散符号应用于它。因此在这两种情况下失败了。
案例是:
array.length === 1
案例中返回数字,而不是数组。array.length
不是1且rest.length
为0的情况下,您没有返回任何内容,因此在这种情况下调用double
的结果为{{1} }。您正试图先尝试传播号码,例如:
undefined

对于#1,您应该返回一个包含一个条目的数组。对于#2,您应该返回function a() {
return 42;
}
const b = [...a()];
。所以最小的变化版本是:
[]

答案 2 :(得分:3)
只是一个小小的改变:
function double(array) {
// note the return here is an array, not a number
if (array.length === 1) return [2 * array[0]];
var [num, ...rest] = array;
if (rest.length) return [2 * num, ...double(rest)];
}
console.log(double([1, 2, 3, 4]));
您正在返回一个号码,并且对数字进行解构会给您留下错误。
...5 // throws SyntaxError
答案 3 :(得分:1)
以下是使用node@6.10.3
if (rest.length!=0) return [2*num, ...double(rest)];
^
TypeError: double(...)[Symbol.iterator] is not a function
at double (/home/henrique/labs/test.js:4:41)
at double (/home/henrique/labs/test.js:4:41)
at Object.<anonymous> (/home/henrique/labs/test.js:7:1)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:390:7)
这可能意味着对某些函数调用的评估结果不是可迭代的。
错误在于:
if (array.length===1) return 2*array[0];
更改为:
if (array.length===1) return [2*array[0]];
它会起作用。