【问题标题】:Why doesn't .join() work with function arguments?为什么 .join() 不能与函数参数一起使用?
【发布时间】:2010-01-19 04:46:33
【问题描述】:

为什么会这样(返回“一、二、三”):

var words = ['one', 'two', 'three'];
$("#main").append('<p>' + words.join(", ") + '</p>');

这项工作(返回“列表:111”):

var displayIt = function() {
    return 'the list: ' + arguments[0];
}   
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');

但不是这个(返回空白):

var displayIt = function() {
    return 'the list: ' + arguments.join(",");
}   
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');

我必须对我的“参数”变量执行什么操作才能在其上使用 .join()?

【问题讨论】:

标签: javascript jquery join


【解决方案1】:

它不起作用,因为arguments 对象不是一个数组,尽管它看起来像它。它没有join 方法:

>>> var d = function() { return '[' + arguments.join(",") + ']'; }
>>> d("a", "b", "c")
TypeError: arguments.join is not a function

要将arguments 转换为数组,您可以:

var args = Array.prototype.slice.call(arguments);

现在join 可以工作了:

>>> var d = function() {
  var args = Array.prototype.slice.call(arguments);
  return '[' + args.join(",") + ']';
}
>>> d("a", "b", "c");
"[a,b,c]"

或者,您可以使用 jQuery 的 makeArray,它会尝试将像 arguments 这样的“几乎数组”转换为数组:

var args = $.makeArray(arguments);

以下是 Mozilla reference(我最喜欢的此类资源)对此的评价:

arguments 对象不是数组。 它类似于数组,但确实 没有任何数组属性,除了 length。例如,它没有 流行的方法。 ...

arguments 对象仅可用 在一个函数体内。试图 访问 a 之外的参数对象 函数声明导致 错误。

【讨论】:

  • Array.join(arguments, ",")(如Array.forEach(arguments, func);
  • 当您的参数之一是对象时会发生什么?
  • @Anonymous TypeError: Object function Array() { [native code] } has no method 'join'
  • Array.prototype.join.call(arguments, ', ')
【解决方案2】:

如果您对其他Array.prototype 方法不感兴趣,而只想使用join,则可以直接调用它,无需将其转换为数组:

var displayIt = function() {
    return 'the list: ' + Array.prototype.join.call(arguments, ',');
};

另外,您可能会发现知道逗号是默认分隔符很有用,如果您没有定义分隔符,spec 将使用逗号。

【讨论】:

  • +1 这是最快和最安全的答案 IF 您想要的只是调用 join 而不是创建新数组。当 join 也适用于类似数组的对象时,调用 slice 只是为了 join 将分配内存。
【解决方案3】:

你可以用这个jQuery .joinObj Extension/Plugin我做的。

正如您将在该小提琴中看到的那样,您可以按如下方式使用它:

$.joinObj(args, ",");

$.(args).joinObj(",");

插件代码:

(function(c){c.joinObj||(c.extend({joinObj:function(a,d){var b="";if("string"===typeof d)for(x in a)switch(typeof a[x]){case "function":break;case "object":var e=c.joinObj(a[x],d);e!=__proto__&&(b+=""!=b?d+e:e);break;default:"selector"!=x&&"context"!=x&&"length"!=x&&"jquery"!=x&&(b+=""!=b?d+a[x]:a[x])}return b}}),c.fn.extend({joinObj:function(a){return"object"===typeof this&&"string"===typeof a?c.joinObj(this,a):c(this)}}))})(jQuery);

【讨论】:

  • 还有……为什么是-1?这是一个完全按照要求工作的插件吗?
  • 我也讨厌它,当人们在没有解释的情况下 -1 我的帖子时.. +1 为你.. T^T
【解决方案4】:

只需使用 jQuery 实用函数makeArray

arguments 不是一个数组,它是一个对象。但是,由于它非常“类似数组”,您可以调用 jQuery 实用函数 makeArray 使其工作:

var displayIt = function() {
    return 'the list: ' + $.makeArray(arguments).join(",");
}   
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');

将输出:

<p>the list: 111,222,333</p>

【讨论】:

    【解决方案5】:

    目前你不能加入数组参数,因为它们不是数组,shown here

    所以你必须先把它们变成这样的数组,

    function f() {
      var args = Array.prototype.slice.call(arguments, f.length);
      return 'the list: ' + args.join(',');
    }
    

    或者像这样,短一点

    function displayIt() {
      return 'the list: ' + [].join.call(arguments, ',');
    }
    

    如果你正在使用类似babel 的东西或兼容的浏览器来使用 es6 功能,你也可以使用 rest 参数来做到这一点。

    function displayIt(...args) {
      return 'the list: ' + args.join(',');
    }
    
    displayIt('111', '222', '333');
    

    这会让你做更酷的事情,比如

    function displayIt(start, glue, ...args) {
      return start + args.join(glue);
    }
    
    displayIt('the start: ', '111', '222', '333', ',');
    

    【讨论】:

      【解决方案6】:

      您可以使用 typeof 来查看这里发生了什么:

      >>> typeof(['one', 'two', 'three'])
      "object"
      >>> typeof(['one', 'two', 'three'].join)
      "function"
      >>> typeof(arguments)
      "object"
      >>> typeof(arguments.join)
      "undefined"
      

      在这里您可以看到 typeof 在两种情况下都返回“object”,但只有一个对象定义了连接函数。

      【讨论】:

        【解决方案7】:

        不知道有没有简单的方法把参数转换成数组,但是你可以试试这个:

        var toreturn = "the list:";
        for(i = 0; i < arguments.length; i++)
        {
           if(i != 0) { toreturn += ", "; }
           toreturn += arguments[i];
        }
        

        【讨论】:

          【解决方案8】:

          arguments 不是一个 jQuery 对象,只是一个普通的 JavaScript 对象。在您尝试致电.join() 之前扩展它。我想你会写:

          return 'the list:' + $(arguments)[0];
          

          (我对jQuery不太熟悉,只会Prototype,所以我希望这不是完全伪造的。)

          编辑:错了!但在他的回复中,Doug Neiner 描述了我正在努力实现的目标。

          【讨论】:

          • 这不太对; arguments 不是数组。相反,它是一个“类似数组的对象”。
          • 一个普通的JS数组支持join
          • 如果 arguments 不是数组,arguments[0] 和 arguments[1] 怎么会给我传递给函数的正确值?
          • Edward:JavaScript 对象可以像响应 .foo 一样响应 [x],这不是只有数组对象才能像其他语言那样做的事情。我认为。我以前错了;)
          • @Edward Tanguay:这是一个不是数组但看起来像一个数组的 javascript 对象:{1:'hello',2:'world',length:2}。请注意,该对象只有 3 个属性:1,2 和长度。它没有附加任何方法。 arguments 对象类似,getElementsByTagName 的结果是另一个。
          猜你喜欢
          • 2020-04-28
          • 1970-01-01
          • 1970-01-01
          • 2020-05-28
          • 2014-04-13
          • 1970-01-01
          • 2017-07-03
          • 2022-01-21
          • 1970-01-01
          相关资源
          最近更新 更多