Question

I am having trouble reassigning functions. I want to assign a previously defined function, drawScene a different method.

function fSwap(funcName, code) {
    eval(funcName) = eval(code);
}
fSwap("drawScene", "function drawScene() { /* Do something */ }");

I feel like this should work, but for some reason eval(funcName) is not an lvalue and it returns the error ReferenceError: invalid assignment left-hand side. All the more puzzling is:

var a = function test() {return 0;};
alert(a === eval("a"));
eval("a") = function test() {return 1;};

Gives an alert with true but does not let me assign to the function a.

My only guess is that eval() does not return lvalues for security reasons. If so, how can I implement fSwap() such that it takes in two strings and assigns the code to the given function name?

Was it helpful?

Solution

You should instead use a callback function. You can do that like this:

function fSwap(funcName, callback) {
    window[funcName] = callback;
}
fSwap("drawScene", function drawScene() { /* Do something */ });

To answer your question directly, what's going wrong is that you're assigning a value to an evaluated piece of code. That won't work. What would work would be:

function fSwap(funcName, code) {
    eval(funcName+' = '+code);
}

but please do not do it this way. The other way, using callback functions, is much cleaner. It's almost always better not to use eval whenever it's not absolutely required to use it. (According to your comment, apparently it is absolutely required to use strings, so do use this piece of code).

OTHER TIPS

I'm late to the party but the following should work for taking a user-input string as a function.

var foo=function(){alert("foo");};
foo();//alerts 'foo'

function fSwap(funcName, fn) {
    eval("newfunc = "+fn);
    window[funcName] = newfunc;
}
fSwap("foo","function(){alert('bar');}");

foo();//alerts 'bar'

DEMO: jsbin

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top