JavaScript:.push不是一个函数。

9

我遇到了代码问题:

var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(reduce(arrays,function(array,b){
  return array.push(b);
}));

function reduce(array,combine){
  var current = [];
  for(var i = 0;i<array.length;i += 1){
    current = combine(current,array[i]);
  }
  return current;
}
console.log(reduce([1, 2, 3, 4], function(array, b) {
  return array.push(b);
}));

// → [1, 2, 3, 4, 5, 6]

I get this error:

TypeError: array.push is not a function (line 3) 

据我所知,这是因为它将数组参数视为与数组不同的东西。然而,我认为我已经传递了变量“current”,它是一个数组。有人能解释一下问题吗?谢谢。

是的,刚刚注意到了。谢谢。 - lintmouse
为什么不使用内置的[].reduce()? - dandavis
@dandavis 我猜他是用这个作为练习来学习如何编写更高级的函数。 - Barmar
3
array.push 返回下一个可用的索引,不能在数字上使用 push - Tushar
1
你知道你可以像这样做吗:var flattened = [].concat.apply([],arrays) 来获得相同的结果吗? - epascarello
2
你已经有了所有的日志记录,但最有用的地方应该是在第一个reduce()调用中的console.log(array),因为这个变量和对它的.push()是你得到这个错误的地方。 - Julian Fondren
7个回答

18

Array.push 不会返回一个数组,它会返回被调用后该数组的新长度。

因此你的 return array.push(b); 返回的是一个 int。这个 int 作为 array 被传回……但是它不是一个数组,所以它没有 .push() 方法。

你需要做的是:

array.push(b);
return array;

3
只返回数组,请参见下面代码:

http://jsfiddle.net/0en82r7t/1/

var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(reduce(arrays,function(array,b){
  array.push(b);
  return array;
}));

function reduce(array,combine){
  var current = [];
  for(var i = 0;i<array.length;i += 1){
    current = combine(current,array[i]);
  }
  return current;
}
console.log(reduce([1, 2, 3, 4], function(array, b) {
  array.push(b)
  return array;
}));

array.push并不返回一个数组,而是返回新的长度

此外,我知道这只是一个测试,但在将来和真正的应用程序开发中,请不要将Array命名为array。使用更详细和清晰的命名,例如:numGroupArray,datesArray,timeArray,tagsArray...


我认为将其命名为 array 只是个人喜好。 - Derek 朕會功夫
是的,array.push()返回数组的长度,所以当在下一次迭代中调用combine时,current不再是一个数组而是一个整数。 - lintmouse
虽然这样做可以解决问题,但请解释一下问题的原因,以便OP或任何其他阅读此内容的用户不会再次提出同样的问题。 - Tushar
谢谢,我没意识到返回array.push会这样。简单的错误居然没被我发现,真不敢相信。 - Devilius

3
问题在于array.push(b)返回的是array的新长度。因此,在第一次调用combine(current, array[i])后,array的长度将被返回,current变成一个integer。由于current在下一次迭代中传递给combine(current, array[i]),JavaScript会抛出TypeError。你对combine(current, array[i]的实现应该像这样:
function(array, b) {
    array.push(b);
    return array;
}

1
ES6解决方案:
reduce([1, 2, 3, 4], (array, b) => [...array, b], [])

0

我知道这个问题早已解决,但是它并没有直接解决我的问题。在寻找解决方案时,我发现了另一种方法,即如果我们想直接返回数组,则可以避免使用 .push() 方法。

return [ ...array, b];

正如在此视频中的1小时41分钟处所解释的那样https://www.youtube.com/watch?v=oBt53YbR9Kk&t=199s


0

我不理解 reduce 函数在做什么,但问题是 Array.prototype.push 返回数组的长度。

var array = [1,2,'b'];
var val = array.push('foo');
// val === 4;

因此,不要在循环的每次迭代中重新设置当前值,只需调用函数,因为.push()会直接修改数组。
function reduce(array,combine){
  var current = [];
  for(var i = 0;i<array.length;i += 1){
    combine(current,array[i]);
  }
  return current;
}

0

看起来你的实现有问题:

function(array, b) {
  return array.push(b);
}

你从这个函数返回的不是一个数组。

return array.push(b);

在执行 push 操作后,返回数组的长度。

因此,您应该修改您的函数为:

function(array, b) {
  array.push(b);
  return array;
}

这可能会起作用。祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接