2

コードから始めましょう:

function say(name) {
    var ghost=function () {
        function ghost() {
            alert('!');
        };

        return body;
    };

    eval("var body=''+"+name+';');
    eval(name+('=('+ghost).replace('body', body)+')();');
    eval(name+'();');
}

function Baal() {
    if ('undefined'===typeof ghost) {
        say('Baal');
        return;
    }

    ghost();
}

say('Baal'); // or just Baal();

悪魔の名前が彼の存在を呼び起こすと言っているように見えます (まあ、彼は精神的な憑依のために誰かを必要としているのかもしれません) ..

ご覧のとおり、ゴーストは とともに存在しませんが、Baalに があるので呼び出すことができます。evalsay(name)

say(name)Baalクロージャとしてコード本体に 再割り当てし、ghostメソッドをキャプチャします。これが動作の仕組みです。しかし、私は避けようとしていevalます..

だから..質問を言い換えさせてください:

を使用せずに、存在しない (メンバーまたはグローバルではない) メソッドを呼び出し可能にするにはどうすればよいevalですか?

4

4 に答える 4

2

私がそれを理解していることを確認するために、あなたの質問を言い換えさせてください. 関数を指定すると、そのスコープがグローバル スコープまたは呼び出し元とサブジェクト間で共有されるスコープになることなく、新しい変数をそのスコープに配置する必要がevalありnew Functionます。

できません。

あなたが今言及したケースではbase()、 を使用する 1 つの関数 を定義できますarguments.callee.caller

そうしないでください。

于 2013-09-30T19:00:34.363 に答える
0

私が理解していれば、eval のエイリアスを作成したいようです:

#Note this code is not intended as a solution, but demonstrates
#an attempt that is guaranteed to fail.
#
function myAlias(ctx) {
eval.call(ctx, 'var ghost = 42');
}

myAlias(this);
alert(ghost);

Javascript では、特にクロージャを使用して多くのファンキーな手先の早業を行うことができますが、これはおそらく JavaScript が実行できない唯一の不可能なことです。私はこれとまったく同じことをしようと長い間試みましたが、eval を再コンテキスト化またはエイリアス化することはできないというブラウザからの苦情に遭遇するだけであると言えます。

于 2013-09-30T19:14:00.477 に答える
0

あなたのコードを読んで、それで何を達成しようとしているのかを理解するのは非常に困難ですが、現在のスコープに変数を導入して呼び出すことができるようにしようとしているようです。あなたが示した方法でJavaScriptでこれを行うことはできません。スコーピングは「下に流れる」だけです。つまり、関数内で定義された変数または関数は、その関数とその中で定義された他の関数でのみ使用できるということです。ゴーストという名前の関数は、その関数がいつ評価されるかに関係なく、それが定義されている関数内でのみ使用できます。

ただし、できることは、関数を返す関数を作成することです。次に、その関数を呼び出して、機能を公開するスコープ内の変数に結果を割り当てることができます。これを行うと、次のようになります。

function defineSpecialAlert() {
    return function(name) {
        alert(name + "!");
    };
}

var newlyDefinedMethod = defineSpecialAlert();

newlyDefinedMethod("Baal");
于 2013-09-30T19:28:21.430 に答える