É possível enviar um número variável de argumentos para uma function JavaScript?

É possível enviar um número variável de argumentos para uma function JavaScript, a partir de uma matriz?

var arr = ['a','b','c'] var func = function() { // debug alert(arguments.length); // for(arg in arguments) alert(arg); } func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d' func(arr); // prints 1, then 'Array' 

Eu escrevi recentemente muito Python e é um padrão maravilhoso poder aceitar varargs e enviá-los. por exemplo

 def func(*args): print len(args) for i in args: print i func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d' func(*arr) // prints 4 which is what I want, then 'a','b','c','d' 

É possível em JavaScript enviar uma matriz para ser tratada como a matriz de argumentos?

Use aplicar :

 var arr = ['a','b','c']; var func = function() { alert(arguments.length); for(var i = 0; i < arguments.length; i++) { alert(arguments[i]); } }; func.apply(null, arr); 

Observe que null é usado como o primeiro argumento de apply, que irá definir a palavra-chave this para o object Global (window) dentro de func .

Observe também que o object arguments não é realmente um Array, você pode convertê-lo por:

 var argsArray = Array.prototype.slice.call(arguments); 

E talvez seja útil para você saber quantos argumentos uma function espera:

 var test = function (one, two, three) {}; test.length == 3; 

Mas de qualquer maneira você pode passar um número arbitrário de argumentos ...

Você pode realmente passar quantos valores quiser para qualquer function javascript. Os parâmetros nomeados explicitamente receberão os primeiros valores, mas TODOS os parâmetros serão armazenados na matriz de argumentos.

Para passar o array arguments no formato “descompactado”, você pode usar apply, assim (cf Functional Javascript ):

 var otherFunc = function() { alert(arguments.length); // Outputs: 10 } var myFunc = function() { alert(arguments.length); // Outputs: 10 otherFunc.apply(this, arguments); } myFunc(1,2,3,4,5,6,7,8,9,10); 

Os operadores splat e spread fazem parte do ES6, a próxima versão planejada do Javascript. Até agora, apenas o Firefox os suporta. Este código funciona no FF16 +:

 var arr = ['quick', 'brown', 'lazy']; var sprintf = function(str, ...args) { for (arg of args) { str = str.replace(/%s/, arg); } return str; } sprintf.apply(null, ['The %s %s fox jumps over the %s dog.', ...arr]); sprintf('The %s %s fox jumps over the %s dog.', 'slow', 'red', 'sleeping'); 

Observe a syntax do awkard para propagação. A syntax usual de sprintf('The %s %s fox jumps over the %s dog.', ...arr); ainda não é suportado . Você pode encontrar uma tabela de compatibilidade do ES6 aqui .

Note também o uso de for...of , outra adição ES6. Usar for...in for arrays é uma má ideia .

A function apply usa dois argumentos; o object ao qual this será vinculado e os argumentos representados com uma matriz.

 some_func = function (a, b) { return b } some_func.apply(obj, ["arguments", "are", "here"]) // "are" 

É chamado de operador de splat . Você pode fazer isso em JavaScript usando apply :

 var arr = ['a','b','c','d']; var func = function() { // debug console.log(arguments.length); console.log(arguments); } func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d' func(arr); // prints 1, then 'Array' func.apply(null, arr); 

Existem dois methods a partir do ES2015.

Os arguments Object

Este object é construído em funções, e refere-se, apropriadamente, aos argumentos de uma function. Não é tecnicamente uma matriz, portanto, operações típicas de matriz não funcionarão nela. O método sugerido é usar Array.from ou o operador spread para criar um array a partir dele.

Eu já vi outras respostas mencionar o uso de slice . Não faça isso. Impede otimizações (fonte: MDN ).

 Array.from(arguments) [...arguments] 

No entanto, eu diria que os arguments são problemáticos porque ocultam o que uma function aceita como input. Uma function de arguments normalmente é escrita assim:

 function mean(){ let args = [...arguments]; return args.reduce((a,b)=>a+b) / args.length; } 

Às vezes, o header da function é escrito da seguinte forma para documentar os argumentos de uma maneira semelhante ao C:

 function mean(/* ... */){ ... } 

Mas isso é raro.

Quanto a por que é problemático, tome C, por exemplo. C é compatível com versões anteriores de um antigo dialeto pré-ANSI da linguagem conhecida como K & R C. O K & R C permite que os protótipos de function tenham uma lista de argumentos vazia.

 int myFunction(); /* This function accepts unspecified parameters */ 

ANSI C fornece um recurso para varargs ( ... ) e void para especificar uma lista de argumentos vazia.

 int myFunction(void); /* This function accepts no parameters */ 

Muitas pessoas inadvertidamente declaram funções com uma lista de argumentos unspecified ( int myfunction(); ), quando esperam que a function receba zero argumentos. Isso é tecnicamente um bug porque a function aceita argumentos. Qualquer número deles.

Uma function varargs adequada em C assume a forma:

 int myFunction(int nargs, ...); 

E o JavaScript realmente tem algo parecido com isso.

Spread Operator / Rest Parameters

Eu já mostrei a você o operador de spread, na verdade.

 ...name 

É bastante versátil e também pode ser usado na lista de argumentos de uma function (“parâmetros de descanso”) para especificar varargs de uma maneira bem documentada:

 function mean(...args){ return args.reduce((a,b)=>a+b) / args.length; } 

Ou como uma expressão lambda:

 ((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3 

Eu prefiro muito mais o operador de spread. É limpo e auto-documentado.

Este é um programa de amostra para calcular a sum de inteiros para argumentos variables ​​e matriz em inteiros. Espero que isto ajude.

 var CalculateSum = function(){ calculateSumService.apply( null, arguments ); } var calculateSumService = function(){ var sum = 0; if( arguments.length === 1){ var args = arguments[0]; for(var i = 0;i 
 (function(window) { var proxied = window.alert; window.alert = function() { return proxied.apply(window, arguments); }; }(this)); alert(13, 37); 

Para aqueles que foram redirecionados aqui de Passando número variável de argumentos de uma function para outra (o que não deve ser marcado como uma duplicata desta questão):

Se você está tentando passar um número variável de argumentos de uma function para outra, desde o JavaScript 1.8.5 você pode simplesmente chamar apply() na segunda function e passar o parâmetro arguments :

 var caller = function() { callee.apply( null, arguments ); } var callee = function() { alert( arguments.length ); } caller( "Hello", "World!", 88 ); // Shows "3". 

Nota: O primeiro argumento é o parâmetro this a ser usado. Passar null chamará a function do contexto global, ou seja, como uma function global em vez do método de algum object.

De acordo com este documento , a especificação ECMAScript 5 redefiniu o método apply() para pegar qualquer “object genérico do tipo array”, em vez de estritamente um Array. Assim, você pode passar diretamente a lista de arguments para a segunda function.

Testado no Chrome 28.0, Safari 6.0.5 e IE 10. Experimente com este JSFiddle .

Sim você pode passar a variável não. de argumentos para uma function. Você pode usar apply para conseguir isso.

Por exemplo:

 var arr = ["Hi","How","are","you"]; function applyTest(){ var arg = arguments.length; console.log(arg); } applyTest.apply(null,arr); 

Com o ES6, você pode usar parâmetros de repouso para varagrs . Isso leva a lista de argumentos e a converte em uma matriz.

 function logArgs(...args) { console.log(args.length) for(let arg of args) { console.log(arg) } }