I would look at whether you can structure things differently. It's usually a big red flag if you're passing around code as text like that, and then eval'ing it. Refactor so you're using proper code if at all possible.
With that out of the way:
I was already looking at the eval and Function() functionality in JS. But I'm not sure if I can solve my problem like this.
Yes, it can. eval
works within the scope where you call it (it's a bit magical in that way). So if you eval
that code within a function, the foo
and bar
it creates will only be created within that function, for the duration of the call to that function (unless you keep a reference to them somewhere).
E.g.:
function blah($scope) {
eval(yourString);
}
...will create foo
and bar
only within that function, and they will have access to the $scope
argument.
(See note below after e
Live Example:
var str = "function foo() { $scope.x = a + b; }";
function bar($scope) {
var a = Math.floor(Math.random() * 10),
b = Math.floor(Math.random() * 10);
eval(str);
foo();
snippet.log("$scope.x = " + $scope.x);
}
snippet.log("typeof foo === " + typeof foo);
bar({});
snippet.log("typeof foo === " + typeof foo);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Final caveat: Be sure you're only calling eval
on code from a trusted source.
It's probably worth noting that this is only true of direct calls to eval
. eval
is very special; if you call it indirectly, via a variable:
var e = eval;
e(yourString);
...that works differently (specifically, it works at global scope, not in the same scope where you called it). This is why you sometimes see code like (0,eval)(string);
: That calls eval
indirectly, making it behave globally rather than locally. (Why not just use var globalEval = eval;
and then globalEval(string);
? Some people are really into their l33t stuff like (0,eval)(...)
. Me, I prefer maintainability, so if I ever needed a global eval [haven't in years], I would go down the globalEval
route...)