Dynamically execute a function in JavaScript
I would like to call a function whose name I have in a variable.
For example:
I get the string"pageTracker._trackpageview('/url/page1.page'); "
dynamically and assign it to a variable as below
var m开发者_StackOverflow中文版yFunction = pageTracker._trackpageview('/url/page1.page');";
Now when I submit the page I want to execute the function which is in variable myFunction.
Thank you all.
function functionFromString(funcDef) {
try {
return (new Function("return function() {" + funcDef + "};"))();
} catch (e) {
alert(e);
return (function() {});
}
}
var myFunction = "pageTracker._trackpageview('/url/page1.page');";
var realFunction = functionFromString(myFunction);
realFunction();
Why do it this way?
Just doing eval runs the function right away. If there are errors thrown in the called function itself we can't tell the difference between that and an error in parsing. So by creating a function out of the text, we can separate when we parse it from when we execute it.
Just using newFunction = Function(myFunction) won't compile it, so it's slower. So using new Function() to return a function (that in turn creates a function) is our trick. We could use eval this way, too, but I like new Function better.
What others have said about being really careful with eval (and new Function()) is true. It can be an opening for malicious script.
You can do this with the JavaScript eval() function. Just be careful about controlling the value passed to eval() as it will execute whatever string it is given.
eval("pageTracker._trackpageview('/url/page1.page');");
You are not simply trying to execute a function whose name you have but a complex line of code with a receiver, a method name and a literal string argument. The only way to execute an arbitrary snippet of codes is with eval()
But eval()
is dangerous. If you're not very careful, someone can pass malignant code to your script that will be executed inside the eval()
call.
You can make use of eval
in javascript..
var myFunction = "pageTracker._trackpageview('/url/page1.page');";
//...
eval(myFunction);
Solution: Wrap the function
//define:
var myFunction = function (){pageTracker._trackpageview('/url/page1.page');}
//call:
myFunction();
Full Example:
<html>
<head>
<script type="text/javascript">
var foo = function (){alert('bar');}
</script>
</head>
<body onload="foo();"> </body>
</html>
But this way, you cannot check if parameter is correct url, or encode it ect. And I avoid eval as hell for known reasons.
I would prefer the harder, but more safe way - if it is a string, it can be parsed:
//test dub
pageTracker = {
_trackpageview: function(path) {alert(path)}
}
var str = "pageTracker._trackpageview('/url/page1.page')";
//get param
var urlpathregex = /\('([a-z0-9\-._~%!$&'()*+,;=:@\/]+)'\)/;
var param = urlpathregex.exec(str)[1];
//do some stuff/validation with param
[...]
//get object and function name
var funcregex = /([a-zA-Z0-9_]+)?\.?([a-zA-Z0-9_]+)(?=\()/;
var match = funcregex.exec(str);
var obj, func;
obj = match[1];
func = match[2];
//invoke
window[obj][func](param);
This is just an example, and not copy&paste ready code :) Because to begin with - if you get dynamically "pageTracker._trackpageview('/url/page1.page')" as a string, there is some code smell here already.
精彩评论