Почему .join () не работает с аргументами функции? - PullRequest
66 голосов
/ 19 января 2010

Почему эта работа (возвращает «один, два, три»):

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 ]

85 голосов
/ 19 января 2010

Это не работает, потому что объект 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 вне объявления функции приводит к ошибке.

19 голосов
/ 19 января 2010

Если вас не интересуют другие методы Array.prototype, и вы хотите просто использовать join, вы можете вызвать его напрямую, без преобразования в массив:

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

Также вы можетеПолезно знать, что запятая является разделителем по умолчанию, если вы не определите разделитель, с помощью spec будет использоваться запятая.

2 голосов
/ 30 марта 2012

Вы можете использовать это 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);
2 голосов
/ 19 января 2010

Просто используйте функцию утилиты 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>
1 голос
/ 19 января 2010

Вы можете использовать typeof, чтобы увидеть, что здесь происходит:

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

Здесь вы можете видеть, что typeof возвращает «объект» в обоих случаях, но только для одного из объектов определена функция соединения.

0 голосов
/ 29 сентября 2015

В настоящее время вы не можете объединить аргументы массива, потому что они не являются массивом, показано здесь

так что сначала вы должны либо превратить их в массив, подобный этому,

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', ',');
0 голосов
/ 19 января 2010

Я не знаю, есть ли простой способ преобразования аргументов в массив, но вы можете попробовать это:

var toreturn = "the list:";
for(i = 0; i < arguments.length; i++)
{
   if(i != 0) { toreturn += ", "; }
   toreturn += arguments[i];
}
0 голосов
/ 19 января 2010

arguments это не объект jQuery, а обычный объект JavaScript. Расширьте его, прежде чем пытаться позвонить .join(). Я думаю, что вы написали бы:

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

(я не слишком знаком с jQuery, только Prototype, поэтому я надеюсь, что это не совсем фальшивка)

Редактировать: Это неправильно! Но в своем ответе Даг Нейнер описывает то, чего я пытаюсь достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...