【问题标题】:Why can't I call an array method on a function's arguments?为什么我不能在函数的参数上调用数组方法?
【发布时间】:2010-11-28 07:47:09
【问题描述】:

我有一个可以接受任意数量参数的函数...

const getSearchFields = () => {        
    const joined = arguments.join('/'); 
};

我想要一个包含所有参数的字符串,这些参数与/ 字符一起传递给函数。我不断收到此错误:

args.join 不是函数

谁能告诉我我做错了什么?

【问题讨论】:

  • 为什么要编辑它以使用 ES6 语法?
  • @TimDown 在我更新它的时候感觉很好。我想有反对这样做的有效论据,如果那是你所暗示的。
  • 我真的不知道,当 2009 年的答案出现在 ES3 中时,这似乎有点奇怪。我现在还没有足够的时间知道将旧问题修改为现代语法是好还是坏。
  • @TimDown AFAIK,即使问题已经过时,我们也鼓励您始终保持答案是最新的。在这种情况下,现在这个问题看起来不那么过时了。
  • @alex,我还更新了my answer 以提供一种 ES6 方式来做到这一点。谢谢。

标签: javascript


【解决方案1】:

arguments 是一个伪数组,而不是一个真正的数组。 join 方法可用于数组。

你需要作弊:

var convertedArray = [];

for(var i = 0; i < arguments.length; ++i)
{
 convertedArray.push(arguments[i]);
}

var argsString = convertedArray.join('/');

与其他帖子类似,您可以将以下内容作为简写:

var argsString = Array.prototype.join.call(arguments, "/");

【讨论】:

  • 要将参数对象转换为数组,您可以简单地:var convertedArray = Array.prototype.slice.call(arguments);
  • 您也可以使用 splice.... 来简化循环。 var args = [].splice.call(arguments,0);
  • @Russ: 更短,但不适用于 IE,你应该直接调用 Array.prototype.slice 函数。
【解决方案2】:

如上所述,arguments 对象并不是真正的数组,但您可以直接应用数组函数,通过访问 Array.prototype 并使用applycall 执行它们来更改上下文:

var argsString = Array.prototype.join.call(arguments, '/');

编辑:由于大约 9 年前提出的原始问题已更新为使用 ES6 语法,我觉得有必要提供 ES6 答案,现在该语言提供了原生结构来处理这种情况。

ES6 标准引入了扩展运算符,你可以很容易地使用它来接收作为数组对象的参数,例如:

function sum(...numbers) {
  return numbers.reduce((sum, value) => sum + value);
}

console.log(sum(1,2,3,4)); // 10

应用于您的示例:

const getSearchFields = (...fields) => {        
  const joined = fields.join('/'); 
};

你也可以使用扩展运算符来进行函数调用,假设你有一个数组,并且你想调用一个函数,将数组的每个元素作为函数调用的参数传递,现在你可以简单地:

function sum(a, b, c, d) {
  return a + b + c + d;
}

var array = [1, 2, 3, 4];
console.log(sum(...array)); // 10

你也可以期待一些参数,并传递参数的 rest 定义为 last 参数:

function processList(first, ...rest) {
  // ...
}

spread 运算符还有更多用途超出了本问题的范围,例如对象复制、在数组中展开数组等...

【讨论】:

  • '/' 需要用括号括起来
  • 不,我正在使用通话,不适用
  • ...更正,这可能需要在调用 apply 时出现。您正在使用通话。我的错。
【解决方案3】:

如果你使用的是jQuery 1.2+,你可以使用$.makeArray():

将类似数组的对象转换为真正的 JavaScript 数组。

从问题中的示例中,只需使用这一行

var args = $.makeArray(arguments);

【讨论】:

  • 只是为了记录,这在 jQuery 1.11.0 中对我有用
【解决方案4】:

arguments 并不是真正的数组。

试试这个:

var args = [].splice.call(arguments,0);
var argsString = args.join('/');

【讨论】:

    【解决方案5】:

    问题在于arguments 是一个类数组对象(它具有映射到传递的参数的编号属性和一个length 属性),但它实际上不是 一个数组。

    在过去,您可以使用Array.prototype.slice.call(arguments)(以及其他方法)将其变成一个真正的数组。

    但是,这些天我们稍微幸运了一些(当然取决于您支持的平台)。你可以这样做......

    const getSearchFields = (...args) => {
       Array.isArray(args); // true
    };
    

    ...或...

    const getSearchFields = () => {
       const args = Array.from(arguments);
       Array.isArray(args); // true
    };
    

    首选第一个示例,因为...

    • 您无需在函数体中执行额外步骤即可正常创建数组
    • arguments 是一个神奇的变量(它没有明确定义,那么它是从哪里来的?)
    • 它有funny behaviour with named args in non-strict mode(请注意,您应该始终'use strict'
    • 第一个示例的意图更加明确(创建一个包含所有参数的数组是明确的)。

    【讨论】:

      【解决方案6】:

      arguments 不是 JavaScript 数组;这是一个没有join 方法的特殊对象。

      【讨论】:

        【解决方案7】:

        如果您在 angular4 用户 HttpHeaders 中发布 http 请求时遇到问题。请检查以下答案。使用 HttpHeaders 后,我的问题得到解决。

        this.headers  = new HttpHeaders({ 'Authorization': token1, 'X-IBM-Client-Id': 'ddddddd' });
        

        values.join is not a function in the file http.es5.js Angular 4

        【讨论】:

          【解决方案8】:

          你必须给一个变量赋值才能工作。

          var a = ['Wind', 'Rain', 'Fire'];
          
          var myVar1 = a.join();
          
          var myVar2 = a.join(', ');
          
          var myVar3 = a.join(' + ');
          
          var myVar4 = a.join('');
          

          【讨论】:

          • 你的陈述不正确,它没有回答问题。
          猜你喜欢
          • 2019-03-02
          • 1970-01-01
          • 1970-01-01
          • 2021-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-17
          相关资源
          最近更新 更多