/ / Permitir argumentos con nombre o argumentos posicionales en Javascript - javascript, paso de parámetros, ecmascript-6

Permitir argumentos con nombre o argumentos posicionales en Javascript - javascript, paso de parámetros, ecmascript-6

¿Cómo puedo hacer que una función acepte ya sea argumentos nombrados (foo({a: "hello", b: "it is me"})) o argumentos posicionales (foo("hello", "it is me"))?

Entiendo que los argumentos nombrados se pueden simular pasando un objeto a la función:

function foo(options) {
options = options || {};
var a = options.a || "peanut"; // whatever default value
var b = options.b || "butter"; // whatever default value
console.log(a, b);
}

// ES6 allows automatic destructuring
function foo({a = "peanut", b = "butter"} = {}) {
console.log(a, b);
}

Pero eso no me permite aceptar argumentos posicionales para ser aprobados.

Me gustaría usar ES6 pero cualquier cosa de ES5 estaría bien también.

Respuestas

1 para la respuesta № 1

En primer lugar, realmente recomendaría seguir con un acercamiento. Como dijiste, usa ya sea "llamado"

function foo({a = "peanut", b = "butter"} = {}) {
console.log(a, b);
}

o argumentos posicionales:

function foo(a = "peanut", b = "butter") {
console.log(a, b);
}

Elija el que mejor se adapte a su función, no mezcle ambos.


Si realmente necesitas ambos por alguna razón, técnicas de sobrecarga estándar están disponibles para usted Solo funcionará correctamente si su primer argumento posicional no es un objeto. Propondría uno de los siguientes modismos:

function foo(a, b) { // positional is normal case
if (arguments.length == 1 && typeof arguments[0] == "object")
{a, b} = arguments[0];

console.log(a, b);
}

function foo({a, b}) { // named is normal case
if (arguments.length > 1 || typeof arguments[0] != "object")
[a, b] = arguments;

console.log(a, b);
}

y si necesita valores predeterminados, se pone feo de cualquier manera:

function foo(a, b) {
var opts = (arguments.length == 1 && typeof arguments[0] == "object")
? arguments[0]
: {a, b};
({a = "peanut", b = "butter"} = opts);

console.log(a, b);
}

1 para la respuesta № 2

Supongo que algo como esto funcionaría:

function foo(...options){
if (typeof options[0] === "object"){
console.log("expect object", options[0]);
}else{
console.log("expect array", options);
}
}

foo("peanut", "butter");
foo({a:"peanut", b:"butter"});

0 para la respuesta № 3

No creo que haya algo incorporado para eso, pero este código debería funcionar para su caso

function foo({a = "peanut", b = "butter"} = {}) {
if (typeof arguments[0] === "string") {
return foo({a: arguments[0], b: arguments[1]})
}
console.log(a, b);
}