JavaScriptのクロージャーと関数の配置
-
04-07-2019 - |
質問
関数の配置は、スコープ内のクロージャーのパフォーマンスに影響しますか?もしそうなら、これらの機能を配置する最適な場所はどこですか?そうでない場合、閉鎖による暗黙の関連付けは、論理的に別の場所に関数を配置するのに十分な理由ですか?
たとえば、 foo が localState の値に依存しない場合、 localState は foo foo の実行時間、メモリ使用量などに影響しますか?
(function(){
var localState;
function foo(){
// code
}
function bar(){
// code
return localState;
}
})();
言い換えれば、これはより良い選択でしょうか?もしそうならなぜですか?
(function(){
function foo(){
// code
}
var localState;
function bar(){
// code
return localState;
}
})();
ダリウスベーコンは、下では、 localState はブロック内のどこからでもアクセスできるため、上記の2つのサンプルは同じです。ただし、ブロックの外部で foo が定義されている以下の例は、異なる場合があります。どう思いますか?
function foo(){
// code
}
(function(){
var localState;
function bar(){
// code
foo();
return localState;
}
})();
解決
Javascriptのすべての関数はクロージャーです。変数が関数によって参照されている場合にのみ、変数の値を解決するランタイムが発生します。たとえば、この例の関数yは、xがyによって直接参照されていない場合でも、xの値をキャプチャします。
var x = 3;
function y() eval("x");
y();
3
他のヒント
これらのスニペットはどちらも同等です。どちらも作成している匿名関数の(同じ)環境で定義されているからです。どちらの方法でも foo
から localState
にアクセスできると思います。
言われていること...作成している環境に不合理な量の変数がある場合、変数の検索に時間がかかる可能性があるため、 foo
の実行時間が影響を受ける可能性があります。 foo
を定義する関数で使用しなくなった変数が大量にあり、 foo
もそれらを必要としない場合、 foo
は、ガベージコレクションされないため、問題になる可能性があります。
犬、宣言の順序がJavaScriptインタープリターによって抽象化されるものになることを願っています。いずれにせよ、パフォーマンスの違いがある場合、これは時期尚早な最適化の悪のポスターの子になるほど最小限になります。
Javaスクリプトは関数スタックの概念を使用しないため、パフォーマンスのオーバーヘッドはないと思います。字句スコープをサポートします。同じ状態がクロージャコール間で実行されます。ちなみに、この例では、ステートメントを実行していないようです!
varまたはfunction宣言のスコープは、宣言がブロック内のどこにあるかに関係なく、それが現れるブロック全体です。効率に影響するのは驚くべきことです。
つまり、" function foo()"は問題ではありません。 &var; var localState"の前または後このブロック内。 " function foo()"が問題になるか このブロックまたはそれを囲むブロック( any ローカル変数を使用しないため、より高いスコープに巻き上げることができる場合)。 Javascriptコンパイラの詳細に依存します。
あなたの例では、違いはあまり重要ではありません。 fooがグローバルスコープにある場合でも、問題はありません。
ただし、関数を変数に割り当てるスタイルを使用して関数を宣言する場合、関数が宣言される順序が非常に問題になる可能性があることに注意してください。
より良いアイデアについては、次の2つの例を試してください。
CheckOne();
function CheckOne() {
alert('check...check one.');
}
CheckTwo();
var CheckTwo = function() {
alert('check...check two.');
};
2番目と1番目の唯一の違いは、関数の宣言に使用するスタイルです。 2番目のものは参照エラーを生成します。
乾杯。