Reputation: 114461
Is it possible to extend dynamically javascript function scope? I tried without success the following:
function foo()
{
var bar = 12;
return function(x)
{
return eval(x);
}
}
var e = foo();
console.log(e("bar")); // 12
console.log(e("bar = 42;")); // 42
console.log(e("bar")); // 42
console.log(e("var baz = 99;")); // undefined
console.log(e("baz")); // ReferenceError: baz is not defined
If however I remove var
from the line baz = 99
then the baz variable becomes a global (this makes perfect sense to me):
...
console.log(e("baz = 99;")); // 99
console.log(e("baz")); // 99
console.log(baz); // 99 (so baz is just a global)
Upvotes: 4
Views: 971
Reputation: 92274
Everytime you call e("var baz = 4")
, it's creating a variable on the stack of that function call, so it's not going to be available the next time you call it.
If you need to dynamically add variables to the scope, I would use Rayno's suggestions, use a map. http://jsfiddle.net/UVSrD/
function foo()
{
var scope = {};
return function(x)
{
return eval(x);
}
}
var e = foo();
console.log(e("scope.bar = 12")); // 12
console.log(e("scope.bar")); // 12
console.log(e("scope.baz = 14")); // 14
console.log(e("scope.baz;")); // 14
// Not a global
console.log(typeof scope) // undefined
Upvotes: 1
Reputation: 3742
Eval will run in the scope of wherever it is called. The behavior you are seeing is because on this line:
console.log(e("var baz = 99;")); // undefined
you create a var baz = 99 in the local scope of the returned function. The return value of var name = value; isn't anything, you you get undefined. when you subsequently call
console.log(e("baz")); // ReferenceError: baz is not defined
you return a new function, where baz hasn't been defined.
This is kinda cool: http://www.bennadel.com/blog/1926-Exploring-Javascript-s-eval-Capabilities-And-Closure-Scoping.htm
Upvotes: 0
Reputation: 94429
You're creating a closure using this code:
function foo()
{
var bar = 12;
return function(x)
{
return eval(x);
}
}
When you pass in bar your overriding the bar variable that has already been initiated to 12. I'm not sure what your trying to accomplish, but using a closure will retain the outer functions variables.
Upvotes: 0