扩展javascript函数范围

时间:2012-04-03 19:31:17

标签: javascript dynamic scope

是否可以动态扩展javascript函数范围?我没有成功尝试以下内容:

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

但是,如果我从行var中移除baz = 99,那么baz变量将变为全局变量(这对我来说非常合理):

...
console.log(e("baz = 99;"));     // 99
console.log(e("baz"));           // 99
console.log(baz);                // 99 (so baz is just a global)

3 个答案:

答案 0 :(得分:1)

每次调用e("var baz = 4")时,它都会在该函数调用的堆栈上创建一个变量,因此下次调用它时它将无法使用。

如果您需要动态地向范围添加变量,我会使用Rayno的建议,使用地图。 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

答案 1 :(得分:0)

您正在使用此代码创建闭包:

function foo()
{
    var bar = 12;
    return function(x)
    {
        return eval(x);
    }
}

当您传入bar时,覆盖已经启动的bar变量为12.我不确定您要完成什么,但使用闭包将保留外部函数变量。

答案 2 :(得分:0)

Eval将在任何调用范围内运行。你看到的行为是因为在这一行:

console.log(e("var baz = 99;")); // undefined

在返回函数的本地范围内创建var baz = 99。 var name = value的返回值;不是什么,你得到不确定。当你随后打电话

console.log(e("baz"));           // ReferenceError: baz is not defined

你返回一个新函数,其中baz尚未定义。

这很酷:http://www.bennadel.com/blog/1926-Exploring-Javascript-s-eval-Capabilities-And-Closure-Scoping.htm