2

重複の可能性:
JavaScript の eval 関数を使用するのはなぜ悪い考えなのですか?

window[]();そのため、とを使用して、文字列から関数を呼び出すさまざまな方法を読みましたeval();。私の状況(以下)では、どの方法が正確に正しい方法なのか、もしそうなら、その理由を説明してください。eval();多くの人がセキュリティと言っていますが、そのページのスクリプトを変更できるブラウザプラグインを入手できる場合、セキュリティが問題になるのはなぜですか? (例: firefox の firebug)

私の現在のコード:

funcOne(target).funcTwo(x, y, z);

推奨されるwindow[]();方法を使用してこれをどのように呼び出すでしょうか? そして、なぜこれを使用できないのですか?:

eval('funcOne(target).funcTwo(x, y, z)');

この質問が何度も聞かれることに悩まされたくありません。なぜなら、私は現在、二重関数を呼び出す方法を考えられないからです。

前もって感謝します!

4

1 に答える 1

6

Javascript では、構文a.bを に置き換えることができますa["b"]。したがって、あなたの場合は使用できます

window["funcOne"](target)["funcTwo"](x, y, z);

もちろん、との代わりに変数を使用している場合にのみ意味が"funcOne"あり"funcTwo"ます。

代わりにすべてが修正されたが、単に実行を遅らせたい場合は、匿名クロージャーで「サンキング」を使用できます

x = function(){ return funcOne(target).funcTwo(x, y, z); };

で評価しx()て、後で目的の結果を得ることができます。

最後の例は、サンク クロージャがそれらを「キャプチャ」するため、変数targetxyおよびが囲んでいるスコープに対してローカルであっても正しく機能します。z

ただし、Javascript で新しいスコープを作成する唯一の方法は関数を使用することであることに注意してください (ブロックは C++ や他の言語で発生するようなスコープではありません) {}

ループ内に複数のクロージャーを作成する必要がある場合、これは逆行する可能性があり、非常によくある間違いの原因となります...

for (var i=0; i<options.length; i++)
{
    var menu_item = document.createElement("div");
    menu_item.textContent = "Option " + i;
    menu_item.onclick = function () {
        // Warning this will NOT work. All divs will
        // alert using the same number!
        alert("Option " + i + " selected");
    }
    menu.appendChild(menu_item);
}

ここでは、div のイベントにクロージャーを使用しましたonclickが、これらの関数はすべてまったく同じi変数を使用するため、これは機能しません。Javascript でスコープを作成する唯一の方法は関数を使用することであるため、解決策は次のとおりです。

for (var i=0; i<options.length; i++)
{
    var menu_item = document.createElement("div");
    menu_item.textContent = "Option " + i;
    (function(i){
         menu_item.onclick = function () {
             alert("Option " + i + " selected");
         };
     })(i); // Pass current `i` as parameter
    menu.appendChild(menu_item);
}

このようにして、ハンドラーi内の変数onclickはクロージャーごとに異なります。

すぐに呼び出すためだけに関数を作成するこのパターンは、多くの独立したクロージャーを作成する必要がある場合に Javascript でよく使用されるため、知って理解することをお勧めします。

于 2012-10-21T08:32:56.827 に答える