I'm trying to remove the eval statement in this function. I'm used to the this[whatever] style replacement but it doesn't work out in this instance.
Have a look:
var App = (function(fw) {
var somevar1 = "hello";
var somevar2 = "world";
this.get = function(what) {
return eval(what);
}
});
var app = new App({some: "thing"});
// now for the use:
console.log(app.get("somevar1"),app);
In the function, all my normal "eval scrubbing" options are not working for instance, I cant use:
return this[what]
return [what]
return app[what]
return new Function(what);
surely this isn't an odd case where eval is necessary? .. ps I have to note that I CANNOT rescope the variables inside App as it's part of a huge codebase.
Here's something to fiddle with:
http://jsfiddle.net/xAVYa/
Unfortunately, you're out of luck; eval
is the only thing that can access variables like that. Next time, don't do things that way :)
You can start a migration by keeping a data
object:
var App = (function(fw) {
var data = {
somevar1: "hello",
somevar2: "world"
};
this.get = function(what) {
return data[what];
};
});
And just gradually do this across the entire codebase where you see it. It shouldn't break anything.
You cannot access an arbitrary local variable by string name without eval. So, unless you're willing to change how those variables are accessed by other code inside of the app
function, you will have to stick with eval (as ugly as it seems).
If, on the other hand, you're willing to change the code inside of the app()
function that accesses somevar1
and somevar2
, then you have options. Note, you shouldn't have to change anything outside the app()
function because you can keep the same contract for the .get()
function so this isn't one of those arbitrarily hard to find all possible places everywhere in the project that might be accessing these variables. Because of the way they are currently declared, they can only be accessed directly from inside the app()
function so your search/replace would be limited to that scope.
If it's OK for the variables to be properties of your object, you could do this:
var app = function(fw) {
this.somevar1 = "hello";
this.somevar2 = "world";
this.get = function(what) {
return this[what];
}
};
var app = new App({some: "thing"});
// now for the use:
console.log(app.get("somevar1"));
console.log(app.somevar1);
console.log(app["somevar1"]);
There isn’t a dynamic way to do this without eval. If the variables aren’t changing, though, you could try something like this:
var App = (function(fw) {
var somevar1 = "hello";
var somevar2 = "world";
this.get = function(what) {
switch (what) {
case "somevar1":
return somevar1;
case "somevar2":
return somevar2;
}
}
});