Call a javascript function in which a member of an object by name

I want to pass a link to an arbitrary function by name to another javascript function. If it's just a global function, no problem:

function runFunction(funcName) { window[funcName](); } 

But suppose a function can be a member of an arbitrary object, for example:

 object.property.somefunction = function() { // } 

runFunction("object.property.somefunction") does not work. I know I can do this:

window["object"]["property"]["somefunction"]()

So, although I could write code to parse the string and understand this hierarchy, it seems to work :) So I thought if there was a better way around this, besides using eval()

+4
source share
3 answers

Nope - besides using eval I don’t know any other way to go down the tree of objects in JavaScript than building walkers - fortunately, this is easy to do:

 /** * Walks down an object tree following a provided path. * Throws an error if the path is invalid. * * @argument obj {Object} The object to walk. * @argument path {String} The path to walk down the provided object. * @argument return_container {Boolean} Should walk return the last node *before* the tip * (ie my_object.my_node.my_other_node.my_last_node.my_attribute) * If `true` `my_last_node` will be returned, rather than the value for `my_attribute`. * @returns {Mixed} Object or the value of the last attribute in the path. */ function walk_path(obj, path, return_container) { return_container = return_container || false; path = path_to_array(path, "."); var ln = path.length - 1, i = 0; while ( i < ln ) { if (typeof obj[path[i]] === 'undefined') { var err = new ReferenceError("The path " + path.join(".") + " failed at " + path[i] + "."); err.valid_path = path.slice(0,i); err.invalid_path = path.slice(i, ln+1); err.breaking_point = path[i]; throw err; } else { var container = obj; obj = obj[path[i]]; i++; } } // If we get down to the leaf node without errors let return what was asked for. return return_container ? container : obj[path[i]]; }; /** * path_to_array * * @argument path {string} A path in one of the following formats: * `path/to/file` * `path\\to\\file` * `path.to.file` * `path to file` * @argument sep {string} optional A seperator for the path. (ie "/", ".", "---", etc.) * * If `sep` is not specified the function will use the first seperator it comes across as the path seperator. * The precedence is "/" then "\\" then "." and defaults to " " * * returns {Array} An array of each of the elements in the string ["path", "to", "file"] */ function path_to_array(path, sep) { path = is_string(path) ? path : path + ""; sep = is_string(sep) ? sep : path.indexOf("/") >= 0 ? "/" : path.indexOf("\\") >= 0 ? "\\" : path.indexOf(".") >= 0 ? "." : " "; /* Alternately use SLak's sep = is_string(sep) ? sep : /[ \\/.]/; if you want simpler code that will split on *any* of the delimiters by default. */ return path.split(sep); } function is_string(s) { return typeof s === "string"; } 

Then just name it like this:

 walk_path(my_object, "path.to.my.function")(); 
+2
source

You can call funcName.split('.') And loop through the resulting array, for example:

 function runFunction(funcName) { var parts = funcName.split('.'); var obj = window; for (var i = 0; i < parts.length; i++) obj = obj[parts[i]]; return obj(); } 
+7
source

If possible, avoid using eval() when you have a choice.

In your case, you can split the parameter based on '.' and then create

 window["object"]["property"]["somefunction"]() 
0
source

Source: https://habr.com/ru/post/1343018/


All Articles