1

I am looking for a way how to call a nested function when I have its name as string. I am writing a function that returns an object that will do some processing by calling functions that are part of its closure and are intentionally inaccessible from the global scope. The code goes something like this:

function makeHandler() {

  function case1() {
    ...
  }

  function case2() {
    ...
  }

  let handler = {}
  handler.handle = function(div) {
    let divCase = div.getAttribute("data-case");
    //divCase is now either "case1" or "case2". I want to call the correct function. I have:
    ({case1: case1, case2: case2}[divCase])()
  }
  return handler
}

let h = makeHandler()
h.handle(someDiv)

I find this approach unsatisfying, if I add case3 I will have to update the handle function. I'd think that the functions case1 and case2 must be part of some context, just like makeHandler is part of the global context and accessible as property of the window object.

I am aware of the very similar 10 year old question: Calling nested function when function name is passed as a string and I've seen other articles with similar recommendation to what I am doing -- create an object where properties are function names and values are functions themselves. I am looking for a more 'generic' solution.

martin
  • 2,520
  • 22
  • 29

1 Answers1

1

I like using this pattern:

    function makeHandler() {

      const cases = {
        case1: function () {},
        case2: function () {}
      }

      let handler = {}
      handler.handle = function(div) {
        let divCase = div.getAttribute("data-case");
        if (!cases[divCase]) throw 'bad case name';
        cases[divCase]();
      }
      return handler
    }
terrymorse
  • 6,771
  • 1
  • 21
  • 27
  • Similar, except that the cases are separated out from the handle function, so `handle` doesn't need updating. It would be difficult to make this pattern more 'generic' than it is. – terrymorse Apr 13 '20 at 18:16
  • I think my question was really more about reflection in JS. You are right that technically I don't have to update the handle function, but wrapping all functions in another object just so that I can call them is not very elegant either. – martin Apr 13 '20 at 18:22
  • Without a straightforward way to get a list of locally scoped function names, I can't think of a more "elegant" pattern. – terrymorse Apr 13 '20 at 18:44
  • That's my question exactly. Is there _any_ way to get a list of locally scoped functions? – martin Apr 13 '20 at 20:04