6502
6502

Reputation: 114461

Extending javascript function scope

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

Answers (3)

Ruan Mendes
Ruan Mendes

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

Adam Shiemke
Adam Shiemke

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

Kevin Bowersox
Kevin Bowersox

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

Related Questions