9

背景: 私はC ++の独学の趣味レベルの理解を持っており、これはjavascriptの同様の理解に変換されています。javascriptをよりよく理解するために、Googleが同じドメインからの複数の結果を処理する方法の問題を解決するGreasemonkeyスクリプトを作成することにしました。

スクリプトを書いたのですが、驚くほど簡単でした。このスクリプトは他の人にも役立つと思うので、リリースしたいと思います。ただし、その前に、無責任なコードをリリースしていないことを確認したいと思います。

拡張機能の問題としてガベージコレクションが不十分であることがよくあることを知っており、それを防ぐためにjavascriptで何をする必要があるかについて調査しました。答えは、関数にラップされているメモリは、その関数が終了したときに再利用されるということのようです。これは、私が見たいくつかの人気のあるスクリプトが、他の方法では役に立たない関数にラップされた理由を説明しているようです。

これは私をこれらの質問に導きます:

  1. 基本的なJavaScript関数を使用して、メモリがリークしないようにするにはどうすればよいですか?
  2. これは、私が多くのスクリプトで見た答えです。

    (function(){  
        //code goes here    
    })();
    
  3. 上記のコードで、最初の括弧の目的は何ですか?それは私には冗長に思えます。

  4. その行を理解しようとしていたときに、次のように書き直しました。

    (function main(){  
        //code goes here  
    })   
    main();  
    

これは、以前は名前が付けられていなかった関数を呼び出すだけであるという考えです。しかし、これはうまくいきませんでした、なぜですか?

私は一般的な答えにもっと興味があります、しかしそれが必要な場合のためにここに私の現在のコードがあります:http: //pastebin.com/qQWKfnJT

4

3 に答える 3

9

このパターン (関数を括弧のペアで囲み、最初のペアの後に別のペアを配置する) は、「すぐ呼び出した関数式表現」パターン (略して IIFE )呼ばれます。それが行うことは、無名関数を定義してからすぐに実行することです。括弧の最初のセットは、関数が文ではなく式であることを示します。2 番目のセットは、最初の式から返された関数を実行します。

// This:
(function(){
    // Todo: Add code
})();

// Translates *approximately* to this:
var _anonymous_function_2723113 = function() {
    // Todo: Add code
};
_anonymous_function_2723113();
delete _anonymous_function_2723113;

名前を付けたときに関数が機能しない理由については、この件に関するkangaxx の記事、特にNamed Function Expressionsに触れている箇所を読むことをお勧めします。要するに、名前付きの関数(ステートメントではなく) がある場合、その名前は関数のスコープでのみ使用できるはずです。

3 と 4 については、メモリ リークの回避に関しては、IIFE はメモリ リークを回避する方法ではありません (@elclanrs が指摘したように、グローバル スコープの汚染を回避するのに役立つだけです)。メモリ リークを回避するには、循環参照を避けてください (クロージャーは循環参照の原因になる可能性があることに注意してください)。

頑張って、楽しんでください!

于 2012-08-17T01:30:29.757 に答える
0

匿名関数を使用できる例を次に示します。IDを持つ4つの要素(id_1、id_2、id_3 ...)を作成します。それぞれをループして、onclickイベントを割り当てます。

for (var i=0; i<5; i++) {
    document.getElementById("id_"+i).onclick = function()  {alert(i)}
}

ただし、要素をクリックすると、それぞれが同じアラートを表示します-4。理由は、JavaScriptクロージャでは、ローカル変数の最後の値のみが保存されるためです。あなたができること:

for (var i=0; i<5; i++) {
(function(n){
    document.getElementById("id_"+n).onclick = function() {alert(n)};
})(i);

}

于 2012-08-17T01:50:48.147 に答える
-1

SOには、この質問に対する答えがすでにたくさんあります...それは自己実行機能です。多くの場合、コードをグローバル スコープから保護するために使用されます。それは他の方法でも書かれています:

function(){}()
(function(){})()
(function(){}())
!function(){}()
(function(){}).call(this)
于 2012-08-17T01:30:18.743 に答える