javascript - What's the best way to replace eval? - Stack Overflow

admin2025-04-03  0

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:

var actionToCall = this.actionCallback+'("testArgument");';
var functionToInvoke = new Function(actionToCall);
functionToInvoke();

Or is there is a better way to do this?

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:

var actionToCall = this.actionCallback+'("testArgument");';
var functionToInvoke = new Function(actionToCall);
functionToInvoke();

Or is there is a better way to do this?

Share Improve this question edited May 13, 2011 at 14:54 gen_Eric 227k42 gold badges303 silver badges342 bronze badges asked May 13, 2011 at 14:50 chewbchewb 711 gold badge1 silver badge2 bronze badges 4
  • 4 This makes no sense what-so-ever. Why do you need any of these things? Why can't you just call this.actionCallback('testArgument')? If 'this.actionCallback' is a string, well then (it shouldn't be for one, it should just reference the callback) if your trying to send in dynamic parameters from diffren't stages of your code, you can use a partial function application. If you REALLY want to reference functions by a string, you can place those functions in any object, not necessarily the window object, and then call them. – GAgnew Commented May 13, 2011 at 16:12
  • @Greg Agnew The client receives this action name from the server under a string representation. What du you mean by "use a partial function application"? – chewb Commented May 16, 2011 at 9:40
  • en.wikipedia/wiki/Partial_function Its essentially the method of creating a reference to a function where one, two, or all of the parameters are predefined, such that the new 'partial' function can be called at a later state and the non-predefined parameters can then be added. It's not suitable for what you've now described. If your simply receiving a string from the server that specifies a function, just put those functions in an object and call object['functionname'](); – GAgnew Commented May 17, 2011 at 20:54
  • ejohn/blog/partial-functions-in-javascript Although the original link I gave is the logical definition, here is an article by Mr Resig that is in javascript, (probably more helpful..) – GAgnew Commented May 17, 2011 at 20:56
Add a ment  | 

5 Answers 5

Reset to default 4

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)");
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1743623022a213721.html

最新回复(0)