为什么.join()不使用函数参数?

时间:2010-01-19 04:46:33

标签: javascript jquery join

为什么这样做(返回“一,二,三”):

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>');

我必须对我的“arguments”变量做什么才能使用.join()?

8 个答案:

答案 0 :(得分:85)

它不起作用,因为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。例如,它没有   pop方法。 ...

     

arguments对象仅可用   在函数体内。试图   访问a之外的arguments对象   函数声明结果   错误。

答案 1 :(得分:19)

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

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

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

答案 2 :(得分:2)

只需使用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>

答案 3 :(得分:2)

您可以使用我制作的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);

答案 4 :(得分:1)

您可以使用typeof查看此处发生的事情:

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

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

答案 5 :(得分:0)

arguments不是jQuery对象,只是一个常规的JavaScript对象。在尝试呼叫.join()之前将其扩展。我想你会写:

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

(我对jQuery不太熟悉,只有Prototype,所以我希望这不是完全虚假的。)

编辑:这是错的!但在他的回答中,道格内纳描述了我想要实现的目标。

答案 6 :(得分:0)

我不知道是否有一种简单的方法将参数转换为数组,但你可以试试这个:

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

答案 7 :(得分:0)

目前您无法加入数组参数,因为它们不是数组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功能,您也可以使用其他参数执行此操作。

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', ',');