Почему .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() на нем?
Ответы
Ответ 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', ',');