Преобразование массива в список аргументов функции

Можно ли преобразовать массив в JavaScript в последовательность аргументов функции? Пример:

run({ "render": [ 10, 20, 200, 200 ] });

function run(calls) {
  var app = .... // app is retrieved from storage
  for (func in calls) {
    // What should happen in the next line?
    var args = ....(calls[func]);
    app[func](args);  // This is equivalent to app.render(10, 20, 200, 200);
  }
}

person dpq    schedule 22.08.2009    source источник
comment
Проверьте аналогичный вопрос здесь: stackoverflow.com/questions/2856059/   -  person Wilt    schedule 25.02.2014
comment
Думаю, это не имеет значения, но кажется странным, что этот старый вопрос помечен как дубликат нового, на который есть ссылка?   -  person shuckster    schedule 13.06.2017


Ответы (4)


да. В текущих версиях JS вы можете использовать:

app[func]( ...args );

Пользователям ES5 и старше потребуется использовать метод .apply():

app[func].apply( this, args );

Прочтите об этих методах на MDN:

person shuckster    schedule 22.08.2009
comment
window, кажется, не нужно. - person JBCP; 25.09.2014
comment
Это не сработает, если вы хотите вызвать функцию внутри объекта - например, следующее не работает: window.document.execCommand.apply(window,["insertHorizontalRule",false]) - person adib; 03.10.2015
comment
Это потому, что в вашем случае вы должны указать window.document в качестве первого аргумента, а не только window: window.document.execCommand.apply(window.document, ... ) - person shuckster; 16.10.2015
comment
window на самом деле не имеет смысла в средах JavaScript, отличных от браузера, таких как NodeJS, поэтому я бы предложил удалить его из ответа. - person zbr; 14.12.2015
comment
Если вы можете использовать функции ES6, вы даже можете использовать f(...[1,2,3]). - person manixx; 19.01.2017
comment
Еще одна хорошая идея. Сделанный! - person shuckster; 24.01.2017

Очень читаемый пример из другого сообщения на аналогичную тему:

var args = [ 'p0', 'p1', 'p2' ];

function call_me (param0, param1, param2 ) {
    // ...
}

// Calling the function using the array with apply()
call_me.apply(this, args);

И здесь ссылка на исходное сообщение, которое я лично понравился своей читабельностью

person Wilt    schedule 25.02.2014
comment
Если это сработает, почему это не сработает? document.body.setAttribute.apply( this, ["foo", "bar"] ); Мне нужно отправить переменные аргументы различным методам объекта с разными требованиями к аргументам. Быстрое редактирование: очевидно, this должен быть document.body или каким-то другим родителем - person bryc; 25.02.2015
comment
В конструкторе Typescript это вызовет ошибку: Only a void function can be called with the 'new' keyword - person Augie Gardner; 22.10.2016

Возможно, вы захотите взглянуть на аналогичный вопрос, опубликованный о переполнении стека. Для этого используется метод .apply().

person JJ Geewax    schedule 22.08.2009

@bryc - да, можно было вот так:

Element.prototype.setAttribute.apply(document.body,["foo","bar"])

Но это похоже на большую работу и запутывание по сравнению с:

document.body.setAttribute("foo","bar")
person user1527225    schedule 29.10.2015