En PHP hay func_num_args
y func_get_args
, ¿hay algo similar para JavaScript?
En PHP hay func_num_args
y func_get_args
, ¿hay algo similar para JavaScript?
Respuestas:
Uso arguments
. Puedes acceder a él como una matriz. Úselo arguments.length
para la cantidad de argumentos.
Los argumentos son un objeto tipo matriz (no una matriz real). Función de ejemplo ...
function testArguments () // <-- notice no arguments specified
{
console.log(arguments); // outputs the arguments to the console
var htmlOutput = "";
for (var i=0; i < arguments.length; i++) {
htmlOutput += '<li>' + arguments[i] + '</li>';
}
document.write('<ul>' + htmlOutput + '</ul>');
}
Pruébalo...
testArguments("This", "is", "a", "test"); // outputs ["This","is","a","test"]
testArguments(1,2,3,4,5,6,7,8,9); // outputs [1,2,3,4,5,6,7,8,9]
Los detalles completos: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments
ES6 permite una construcción donde se especifica un argumento de función con una notación "..." como
function testArgs (...args) {
// Where you can test picking the first element
console.log(args[0]);
}
a = () => {console.log(arguments);}; a('foo');
da -- Uncaught ReferenceError: arguments is not defined
Sin embargo a = (...args) => {console.log(args);}; a('foo');
da["foo"]
El arguments
objeto es donde se almacenan los argumentos de las funciones.
El objeto de argumentos actúa y parece una matriz, básicamente lo es, simplemente no tiene los métodos que las matrices tienen, por ejemplo:
Array.forEach(callback[, thisArg]);
Array.map(callback[, thisArg])
Array.filter(callback[, thisArg]);
Array.indexOf(searchElement[, fromIndex])
Creo que la mejor manera de convertir un arguments
objeto en una matriz real es así:
argumentsArray = [].slice.apply(arguments);
Eso lo convertirá en una matriz;
reutilizable:
function ArgumentsToArray(args) {
return [].slice.apply(args);
}
(function() {
args = ArgumentsToArray(arguments);
args.forEach(function(value) {
console.log('value ===', value);
});
})('name', 1, {}, 'two', 3)
resultado:
>
value === name
>value === 1
>value === Object {}
>value === two
>value === 3
[].slice.apply(arguments);
no puede ser la mejor manera porque causa una asignación de matriz vacía innecesaria.
También puede convertirlo en una matriz si lo prefiere. Si hay genéricos de matriz disponibles:
var args = Array.slice(arguments)
De otra manera:
var args = Array.prototype.slice.call(arguments);
de Mozilla MDN :
No debe dividir los argumentos porque evita las optimizaciones en los motores de JavaScript (V8, por ejemplo).
function foo() { foo.bar = JSON.stringify(arguments); foo.baz = JSON.parse(foo.bar); }
si se necesita preservación en lugar de stringificación, use el algoritmo de clonación estructurado interno . Si se pasan los nodos DOM, use XMLSerializer como en una pregunta no relacionada . with (new XMLSerializer()) {serializeToString(document.documentElement) }
Como muchos otros señalaron, arguments
contiene todos los argumentos pasados a una función.
Si desea llamar a otra función con los mismos argumentos, use apply
Ejemplo:
var is_debug = true;
var debug = function() {
if (is_debug) {
console.log.apply(console, arguments);
}
}
debug("message", "another argument")
Respuesta similar a Gunnar, con un ejemplo más completo: incluso puedes devolver todo de forma transparente:
function dumpArguments(...args) {
for (var i = 0; i < args.length; i++)
console.log(args[i]);
return args;
}
dumpArguments("foo", "bar", true, 42, ["yes", "no"], { 'banana': true });
Salida:
foo
bar
true
42
["yes","no"]
{"banana":true}
Sí, si no tiene idea de cuántos argumentos son posibles en el momento de la declaración de la función, puede declarar la función sin parámetros y puede acceder a todas las variables mediante una matriz de argumentos que se pasan en el momento de la llamada a la función.
En ES6 puedes hacer algo como esto:
function foo(...args)
{
let [a,b,...c] = args;
console.log(a,b,c);
}
foo(1, null,"x",true, undefined);
En ES6, use Array.from
:
function foo()
{
foo.bar = Array.from(arguments);
foo.baz = foo.bar.join();
}
foo(1,2,3,4,5,6,7);
foo.bar // Array [1, 2, 3, 4, 5, 6, 7]
foo.baz // "1,2,3,4,5,6,7"
Para el código que no es ES6, use JSON.stringify y JSON.parse:
function foo()
{
foo.bar = JSON.stringify(arguments);
foo.baz = JSON.parse(foo.bar);
}
/* Atomic Data */
foo(1,2,3,4,5,6,7);
foo.bar // "{"0":1,"1":2,"2":3,"3":4,"4":5,"5":6,"6":7}"
foo.baz // [object Object]
/* Structured Data */
foo({1:2},[3,4],/5,6/,Date())
foo.bar //"{"0":{"1":2},"1":[3,4],"2":{},"3":"Tue Dec 17 2013 16:25:44 GMT-0800 (Pacific Standard Time)"}"
foo.baz // [object Object]
Si se necesita preservación en lugar de stringificación, use el algoritmo de clonación estructurado interno .
Si se pasan los nodos DOM, use XMLSerializer como en una pregunta no relacionada .
with (new XMLSerializer()) {serializeToString(document.documentElement) }
Si se ejecuta como bookmarklet, es posible que deba ajustar cada argumento de datos estructurados en un constructor de errores para JSON.stringify
que funcione correctamente.
Referencias
function
, no para las=>
funciones de flecha gruesa ES2015 + . Para aquellos, podrás quiero usar...args
en la definición de función, así:(...args) => console.log(args)
.