10

为什么这样使用时会出错arguments

function sum(){
    return arguments.reduce(function(a,b){
        console.log(a+b)
        return a+b;
    },0);
}

sum(1,2,3,4);

错误:

/Users/bob/Documents/Code/Node/hello.js:2
return arguments.reduce(function(a,b){
                 ^
TypeError: Object #<Object> has no method 'reduce'
    at sum (/Users/bob/Documents/Code/Node/hello.js:2:19)
    at Object.<anonymous> (/Users/bob/Documents/Code/Node/hello.js:8:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:903:3

这是来自 Crockford 先生的JS 讲座

4

3 回答 3

28

arguments不是真正的数组,它是“类数组”对象,reduce不是类数组对象的方法。您可以reduce通过arguments作为上下文传递来使用,如下所示:

[].reduce.call(arguments, function(a, b) {

});

编辑:在MDN上有关类似数组的对象的更多信息。

于 2013-03-28T20:11:10.753 回答
1

Crockford 明确指出,在 ECMAscript 5 中引入了在参数上使用诸如 reduce() 之类的 Array 方法。在 ECMAscript5 之前,甚至 Array 在所有 Javascript 实现中都没有 reduce()。对于 map() 和 reduce() 之类的东西,我建议使用像 Underscore 这样的库来隐藏实现差异。

于 2014-05-25T16:27:36.247 回答
0

你得到一个错误,因为arguments是一个对象而不是一个列表。考虑以下:

> function a(){ return arguments; }
> b = a(1, 2, 3);
> b
{ '0': 1,
  '1': 2,
  '2': 3 }

MDN JavaScript 文档arguments有更多信息,包括:

对应于传递给函数的参数的类数组对象。

于 2013-03-28T20:13:34.813 回答