开发者

What's the best way to replace eval?

I deal with a JavaScript code to improve. The idea here is to invoke functions dynamically.

Here is the code to replace:

//this.actionCallback return the name of the function to invoke
eval(this.actionCallback + "('testArgument')");

What is the best way to replace it:

This way:

window[this.actionCallback]("testArgument");

Or this way:

开发者_JAVA百科var actionToCall = this.actionCallback+'("testArgument");';
var functionToInvoke = new Function(actionToCall);
functionToInvoke();

Or is there is a better way to do this?


The first way is a much better method - new Function(actionToCall) is just eval in disguise.


Both of the alternatives you have mentioned are not equivalent to the first one:

  • Your first alternative requires that the function name be the member of window (in other words, defined at global scope). Having a function inside another scope will cause this to fail, but it doesn't use eval. :)

  • Your second alternative creates a function object using the Function() constructor, so this also only works when the function in declared at the global scope, because a function defined by a Function constructor does not inherit any scope other than the global scope, and as said in Jamie Wong's answer, using the Function() constructor is still considered as eval :(

Here is an alternative that should work like your first one, but looks slightly better, but still uses eval.

eval(this.actionCallback)("testArgument");

But the best way is that this.actionCallback should be a real function object, and not just a function's name, then you can call:

this.actionCallback("testArgument");


I would suggest using window[this.actionCallback]("testArgument");.

This way there is no evaling or making anonymous functions. You are just calling the function directly.


In case like this you probably do not want to allow calling arbitrary functions, only "action" functions. Build a list of supported callbacks

actionCallbacks["doWork"] = doWork;

Call them

actionCallbacks[this.actionCallback]("testArgument")

And catch if function does not exist


If the function belongs to an object you can do something like this:

function run(func, object, args = []) {
  object[func]().apply(object, args);
}

Also, here is unique (but not very reliable) way of replacing eval:

function evaluate(code) {
  location.href = "javascript:" + code;
}

evaluate("alert(1)");
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜