4

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)
4

3 に答える 3

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
于 2012-04-03T20:00:10.937 に答える
0

次のコードを使用してクロージャーを作成しています。

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

バーを渡すと、すでに12に開始されているバー変数をオーバーライドします。何を達成しようとしているのかわかりませんが、クロージャーを使用すると、外部関数変数が保持されます。

于 2012-04-03T19:35:38.780 に答える
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

于 2012-04-03T19:54:31.080 に答える