Подтвердить что ты не робот

Почему .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() на нем?

4b9b3361

Ответ 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 (мой любимый ресурс для такого рода вещей):

Объект arguments не является массивом. Он похож на массив, но делает не имеют свойств массива, кроме length. Например, у него нет поп-метод....

Объект arguments доступен только внутри тела функции. Пытаться доступ к объекту аргументов вне объявление функции приводит к ошибка.

Ответ 2

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

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

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

Ответ 3

Просто используйте служебную утилиту 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>

Ответ 4

Вы можете использовать этот 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);

Ответ 5

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

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

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

Ответ 6

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

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

(Я не слишком хорошо знаком с jQuery, только Prototype, поэтому надеюсь, что это не совсем фиктивный.)

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

Ответ 7

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

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

Ответ 8

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

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

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