proposal - ¿Operadores de Splat en JavaScript, equivalentes a*args y** kwargs en Python?
object spread syntax proposal (5)
Utilizo mucho Python, y ahora mismo estoy aprendiendo JavaScript (o debería decir el reaprendizaje). Entonces, quería preguntar, ¿cuál es el equivalente de *args
y **kwargs
en JavaScript?
ECMAScript 6 tendrá parámetros de reposo que hacen lo mismo que el operador splat.
ES6 agregó un operador de extensión a JavaScript.
function choose(choice, ...availableChoices) {
return availableChoices[choice];
}
choose(2, "one", "two", "three", "four");
// returns "three"
El equivalente más cercano es el arguments
pseudo-array .
Encontré una buena solución aquí: http://readystate4.com/2008/08/17/javascript-argument-unpacking-converting-an-array-into-a-list-of-arguments/
Básicamente, use function.apply(obj, [args])
lugar de function.call
. apply toma una matriz como segundo arg y lo ''splats'' por ti.
La expresión más cercana para *args
sería
function func (a, b /*, *args*/) {
var star_args = Array.prototype.slice.call (arguments, func.length);
/* now star_args[0] is the first undeclared argument */
}
aprovechando el hecho de que Function.length
es el número de argumentos dados en la definición de la función.
Puedes empaquetar esto en una pequeña rutina de ayuda como
function get_star_args (func, args) {
return Array.prototype.slice.call (args, func.length);
}
y luego hacer
function func (a, b /*, *args*/) {
var star_args = get_star_args (func, arguments);
/* now star_args[0] is the first undeclared argument */
}
Si está de humor para el azúcar sintáctico, escriba una función que transforma una función en otra a la que se llama con argumentos obligatorios y opcionales, y pasa los argumentos requeridos junto con los argumentos opcionales adicionales como una matriz en la posición final:
function argsify(fn){
return function(){
var args_in = Array.prototype.slice.call (arguments); //args called with
var required = args_in.slice (0,fn.length-1); //take first n
var optional = args_in.slice (fn.length-1); //take remaining optional
var args_out = required; //args to call with
args_out.push (optional); //with optionals as array
return fn.apply (0, args_out);
};
}
Use esto de la siguiente manera:
// original function
function myfunc (a, b, star_args) {
console.log (a, b, star_args[0]); // will display 1, 2, 3
}
// argsify it
var argsified_myfunc = argsify (myfunc);
// call argsified function
argsified_myfunc (1, 2, 3);
Por otra parte, puede omitir todo este "mumbo jumbo" si está dispuesto a pedirle a la persona que llama que pase los argumentos opcionales como una matriz para comenzar:
myfunc (1, 2, [3]);
Realmente no hay una solución análoga para **kwargs
, ya que JS no tiene argumentos clave. En cambio, solo pida a la persona que llama que pase los argumentos opcionales como un objeto:
function myfunc (a, b, starstar_kwargs) {
console.log (a, b, starstar_kwargs.x);
}
myfunc (1, 2, {x:3});
Actualización de ES6
Para completar, permítanme agregar que ES6 soluciona este problema con la característica de parámetro de reposo. Ver http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html .