1

複雑すぎる関数(プロセッサ)に取り組んでいるので、その中にネストされた「ユーティリティ関数」(印刷)に機能の一部を埋め込みました。簡略化したバージョンは次のようになります。

var out = document.getElementById( "output" );

function processor ( n ) {
    function print( msg ) {
        out.innerHTML  += msg;
    }
    while ( n > 0 ) {
        print( n-- );
        print( ", " );
    }
    print( "<br/>" );
}

for ( var i = 0; i < 10; i++ ) {
    processor( i );
}

このJSfiddleで実際の動作を確認できます。

問題は、ユーティリティ関数のインスタンスを実際に10個作成しているのprint()かということです。はいの場合、効用関数を関数の外に置かずにこのコードを書くためのより効率的な方法は何processor()ですか?この関数は、他の場所ではなく、どこprint()からでもアクセスできるようにしたいと思います。processor()1つの解決策は名前空間です。

私はこの質問を読みましたが、それは関連していますが、直接私の答えではありません: ネストされたループでイベントハンドラーを作成する効率:ここで1440関数を作成していますか?

4

2 に答える 2

3

JavaScriptの用語では、そうです。ただし、実際には、JavaScriptエンジン自体が関数を定義するコードを再利用し、再利用のためにスコープを適切に微調整する可能性があります。Chromiumで使用されているこのアプローチについて読みました。

でのみ印刷機能にアクセスできるようにprocessor()するには、IIFEを作成する必要があります。

var out = document.getElementById( "output" );

var processor = (function () { 
    function print( msg ) {
        out.innerHTML  += msg;
    }

    return function ( n ) {
        while ( n > 0 ) {
            print( n-- );
            print( ", " );
        }
        print( "<br/>" );
    };

}());

for ( var i = 0; i < 10; i++ ) {
    processor( i );
}

ループ内ではなくここで関数を再作成する理由は、function(eg processor)が新しいスコープを定義するためですが、ブロック(ループなど)は定義しません。関数宣言は、ブロックではなく、スコープの先頭に引き上げられます。

于 2012-07-02T12:50:17.517 に答える
1

要するに、そうです。ただし、これらはすべて関数ローカルであるため、関数が戻るとスタックからポップされて破棄されます。processor()forループで関数をシリアルに呼び出すため、関数のインスタンスprint()が有効になり、いつでもアクセスできるようになるのは1回だけです。

于 2012-07-02T12:52:01.387 に答える