Javascript: могу ли я вернуть ссылку на функцию, определенную вне функции, которую я вызываю? - PullRequest
1 голос
/ 14 июля 2020

Допустим, у меня есть этот код:

function QueCalculamos(valor) {

    function CalculaADeB() {
      console.log( "Calculando A de B");
      }

    function CalculaBDeA() {
      console.log( "Calculando B de A");
      }


   if (valor =="A") { return CalculaADeB; }
    else if (valor == "B") { return CalculaBDeA; }
}

let bvla="B";

var exe = QueCalculamos(bvla);
exe();

В зависимости от значения, которое я передаю в "QueCalculamos", он выполнит ту или иную функцию.

Но предположим, что я не нужно выбирать между двумя функциями, а среди многих, и что они немного велики. Для удобства чтения кода я хотел бы определить "CalculaADeB" и "CalculaBDeA" отдельно, за пределами "QueCalculamos".

Как мне вернуть ссылку на эти функции в этом случае? А если это невозможно, как бы вы организовали код, чтобы сделать его более читабельным? (Возможно, у меня недостаточно опыта работы с современным Javascript, но вся эта штука «определить функцию внутри функции» всегда кажется мне беспорядочной).

Ответы [ 3 ]

3 голосов
/ 14 июля 2020

Вы можете определить свои функции как методы объекта.

let funcs = {
    func1() { /* ... */ },
    func2() { /* ... */ },
    /* ... */
}

Затем ссылайтесь на них из своей функции маршрутизатора через что-то вроде оператора switch.

function QueCalculamos(valor) {
    switch (valor) {
        case 'A': return funcs.func1;
        case 'B': return funcs.func2;
        /* ... */
    }
}
2 голосов
/ 14 июля 2020

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

let functions = {                                          // keys are the possible values of valor
  "A": function() { /* ... */ },                           // you can either define the functions here
  "B": CalculaBDeA,                                        // ... or assign a reference to an already existing function
  "C": function() { /* ... */ },
  "D": function() { /* ... */ },
  /* ... */
}

function QueCalculamos(valor) {
  if(functions.hasOwnProperty(valor)) {                     // if the functions object contains a function for valor
    return functions[valor];                                // return it
  }

  throw "there is no function for '" + valor + "'";        // otherwise throw an error or return something else to signal failure
}

Демо:

let functions = {
  "A": function() {
    console.log("Function A");
  },
  "B": function() {
    console.log("Function B");
  },
  "C": function() {
    console.log("Function C");
  },
  "D": function() {
    console.log("Function D");
  },
  /* ... */
}

function QueCalculamos(valor) {
  if (functions.hasOwnProperty(valor)) {
    return functions[valor];
  }

  throw "there is no function for '" + valor + "'";
}


let exe = QueCalculamos("C");
exe();
2 голосов
/ 14 июля 2020

Вы можете определять их где угодно, если они входят в область действия QueCalculamos, чтобы вы могли получить к ним доступ (получить ссылку). Единственное отличие состоит в том, что функции больше не будут замыканиями, которые могут получить доступ к valor, но они все равно этого не делают.

Он просто будет работать, если вы переместите их наружу:

function CalculaADeB() {
  console.log("Calculando A de B");
}
function CalculaBDeA() {
  console.log("Calculando B de A");
}

function QueCalculamos(valor) {
  if (valor =="A") { return CalculaADeB; }
  else if (valor == "B") { return CalculaBDeA; }
}

let bvla="B";

var exe = QueCalculamos(bvla);
exe();

Вы можете еще больше упростить код, поместив их в объект с именами свойств, чтобы выбрать их:

const calcs = {
  A() {
    console.log("Calculando A de B");
  },
  B() {
    console.log("Calculando B de A");
  },
};
function QueCalculamos(valor) {
  return calcs[valor];
}

var exe = QueCalculamos("B");
exe();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...