1

Suppose I have a variable that contains the name of a function I want to run, I can run it by using window, like so;

var func = "myFunc",
    myFunc = function(){ ... };

window[func](); // run the function in the func var

However, this doesn't work if the intended function is deep inside an object;

var obj = {
  foo: {
    hey: function(){ ... }
  }
};

obj.foo.hey(); // this runs


var func = "obj.foo.hey";

window[func](); // this doesn't

I could use eval(), but I wonder if it's possible to avoid that, so as to not introduce the many security considerations that eval() comes with.

How can I run a function specified in a variable, when the function is in an object as described above?

Emphram Stavanger
  • 4,158
  • 9
  • 35
  • 63
  • http://stackoverflow.com/questions/1184123/is-it-possible-to-add-dynamically-named-properties-to-javascript-object – Teemu Jan 03 '17 at 12:37

2 Answers2

1

You could iterate the splitted func and return the result of an walked object.

function getValue(object, path) {
    return path.split('.').reduce(function (o, k) {
        return (o || {})[k];
    }, object);
}

var obj = { foo: { hey: function () { console.log('hey'); } } },
    func = "obj.foo.hey";

getValue(window, func)();
(getValue(window, 'bar') || function () {})(); // default function, prevent exception
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You can's pass nested properties under a single string. It must be done dynamically like.

var obj = {
  foo: {
    hey: function(){console.log("i run")}
  }
};

obj.foo.hey(); // this runs


var route = ["obj","foo","hey"],
     func = route.reduce((f,r) => f[r], window);

func()
Redu
  • 25,060
  • 6
  • 56
  • 76