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


71

为什么这样做(返回“ 1、2、3”):

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(),该怎么办?



我已经修改了答案,以考虑到您的最新问题-具体来说,“我必须做什么才能使这项工作成功?” 部分。
约翰·费米内拉

Answers:


92

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参考资料(我最喜欢的这类资源)关于它的内容:

arguments对象不是数组。它类似于数组,但除之外没有任何数组属性 length。例如,它没有pop方法。...

arguments对象仅在功能体内可用。尝试在函数声明之外访问arguments对象会导致错误。


4
Array.join(arguments, ",")(例如Array.forEach(arguments, func);
匿名用户

当您的一个参数是一个对象时会发生什么?
user1876508 2013年

3
@Anonymous类型错误:对象函数阵列(){[本地代码]}没有方法'加入'
drAlberT

5
Array.prototype.join.call(arguments, ', ')
Kirill Slatin

21

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

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

另外,知道逗号是默认的分隔符可能会很有用,如果您未定义分隔符,则按规范将使用逗号。


+1这是最快,最安全的答案,如果您只想调用join而不是创建一个新数组。当join也适用于类似数组的对象时,仅调用slice来联接将分配内存。
Ajax

3

您可以使用我制作的这个jQuery .joinObj扩展/插件

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

$.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);

3
和...为什么为-1?这是一个完全符合要求的工作插头吗?
SpYk3HH

4
我也讨厌它,当人们-1我的帖子没有说明时..为您+1 .. T ^ T
Kokizzu 2012年

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>

2

目前您无法加入数组参数,因为它们不是数组,如下所示

因此,您必须先将它们变成这样的数组,

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

1

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

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

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


1

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

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

0

arguments不是jQuery对象,而是普通的JavaScript对象。在尝试呼叫之前将其扩展.join()。我想你会写:

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

(我对jQuery不太了解,仅对Prototype不太熟悉,所以我希望这不是完全虚假。)

编辑:这是错误的!但是道格·尼纳(Doug Neiner)在回应中描述了我正在努力实现的目标。


2
这不太正确;arguments不是数组。相反,它是一个“类似数组的对象”。
约翰·费米内拉

普通的JS Array支持join
Doug Neiner

如果arguments不是数组,那么arguments [0]和arguments [1]怎么给我传递给函数的正确值?
爱德华·坦格伊

爱德华:JavaScript对象可以像[foo]一样响应[x],这并不是只有数组对象可以像其他语言那样响应。我认为。我之前错了;)
凯文·康纳

@Edward Tanguay:这是一个JavaScript对象,它不是数组,但看起来像一个:{1:'hello',2:'world',length:2}。请注意,该对象仅具有3个属性:1,2和length。它没有附加任何方法。该arguments对象是相似的,getElementsByTagName的结果是另一个。
slebetman 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.