Как сделать так, чтобы функция принимала именованные аргументы (foo({a: 'hello', b: 'it is me'})) или позиционные аргументы (foo('hello', 'it is me'))?

Я понимаю, что именованные аргументы могут быть смоделированы путем передачи объекта в функцию:

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);
}

Но это не позволяет мне принять позиционные аргументы для передачи.

Я хотел бы использовать ES6, но все, что от ES5 тоже будет в порядке.

7
AKG 17 Дек 2015 в 09:17

3 ответа

Лучший ответ

Прежде всего, я действительно рекомендовал бы придерживаться одного подхода. Как вы сказали, используйте либо "named"

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

или позиционные аргументы:

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

Выберите тот, который лучше подходит вашей функции, не смешивайте оба .


Если по какой-то причине вам действительно нужны оба варианта, вам доступны стандартные методы перегрузки. Он будет работать правильно, только если ваш первый позиционный аргумент не является объектом. Я бы предложил один из следующих идиом:

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);
}

И если вам нужны значения по умолчанию, это будет ужасно в любом случае:

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);
}
2
Community 23 Май 2017 в 12:15

Я не думаю, что есть что-то встроенное для этого, но этот код должен работать для вашего случая

function foo({a = 'peanut', b = 'butter'} = {}) {
    if (typeof arguments[0] === 'string') {
        return foo({a: arguments[0], b: arguments[1]})
    }
    console.log(a, b);
}
0
gafi 17 Дек 2015 в 10:42

Я полагаю, что-то вроде этого будет работать:

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'});
1
glued 17 Дек 2015 в 06:41