JavaScriptは包装を閉じます.ブロックレベルの作用領域を模倣します.
4024 ワード
この文章を読む前に、JavaScriptの作用領域チェーンとJavaScriptの閉鎖–概要を読むことをお勧めします.
クローズドの定義と同じように、「クローズドとは、別の関数のスコープにアクセスする変数の関数を意味する」ということであり、クローズドの最大の意味は、クローズドが他の関数のスコープの変数にアクセスすることができ、これによって、クローズドは一連の使用法を拡張することができるということである.
ブロックレベルのスコープを模倣する
JavaScriptには、ブロックレベルのスコープの概念がありません.これは、ブロックステートメントで定義された変数が、ステートメントではなく関数に含まれていることを意味します.この関数の実行時に作成された関数の活動オブジェクトの中には、関数内で定義された変数(すべて、すなわちブロックステートメントに定義された変数も含まれています.)が全部含まれるので、関数内のすべての変数定義から関数内で随所にアクセスできます.例:
関数包装器はブロックの作用領域を模倣してこの問題を回避するために用いることができる.関数包装器は作成してすぐに関数を呼び出します.はすぐに関数のコードを実行し、またメモリに関数の参照を残しません. 関数内部のすべての変数は、作用領域を含む変数にこれらの変数の割り当て値を与えない限り、直ちに破壊されます. 関数内部で関数パッケージングを使用すると、関数パッケージングは閉じられています.外部環境内のすべての変数にアクセスすることができます.
どこにいても、一時的な変数が必要な場合は、ブロックレベルのスコープを使用することができます.
このような関数パッケージングを使用すると、閉塞過多のメモリ占有の問題を減らすことができます.匿名関数への参照がないので、関数パッキンの実行が完了すれば、そのスコープは直ちに廃棄されます.
関数パッケーターという技術は、大域的な作用領域において関数の外部でよく用いられ、大域的な作用領域に過剰な変数と関数を追加することを制限する.一般的には、グローバルスコープに変数と関数を追加することは最小限にしなければなりません.多すぎるグローバル変数と関数は名前の衝突を招きやすいです.ブロックレベルのスコープを作成することで、各開発者は自分の変数を使うことができます.たとえば:
クローズドの定義と同じように、「クローズドとは、別の関数のスコープにアクセスする変数の関数を意味する」ということであり、クローズドの最大の意味は、クローズドが他の関数のスコープの変数にアクセスすることができ、これによって、クローズドは一連の使用法を拡張することができるということである.
ブロックレベルのスコープを模倣する
JavaScriptには、ブロックレベルのスコープの概念がありません.これは、ブロックステートメントで定義された変数が、ステートメントではなく関数に含まれていることを意味します.この関数の実行時に作成された関数の活動オブジェクトの中には、関数内で定義された変数(すべて、すなわちブロックステートメントに定義された変数も含まれています.)が全部含まれるので、関数内のすべての変数定義から関数内で随所にアクセスできます.例:
function outputNumbers(count){
for(var i = 0; i < count; i++){
console.log(i); // 0, 1, ... count - 1
}
console.log(i); // count
}
C+++やJAVAなどの言語では、変数iはforループのブロック(block)に定義があり、ループが終了すると変数iは破棄されます.しかし、JavaScriptでは、変数iはoutputNumbers()の活動対象として定義されていますので、関数内のすべての変数定義から関数内部で随所にアクセスできます.下記のように同じ変数を再宣言しても、その値は変わりません.function outputNumbers(count){
for(var i = 0; i < count; i++){
console.log(i); // 0, 1, ... count - 1
}
var i; // redeclare i
console.log(i); // count
}
JavaScriptはこれまで何度も同じ変数を宣言していたにもかかわらず、この場合、JavaScriptは後続のステートメントを無視して(ただし、後のステートメントの変数初期化を実行します)、これを割当文とします.関数包装器はブロックの作用領域を模倣してこの問題を回避するために用いることができる.関数包装器は作成してすぐに関数を呼び出します.
(function(){
console.log("Hello World!");
})();
このコードは直接出力されます.「ハローワールド」という関数包装器です.関数包装器の役割:function outputNumbers(count){
(function(){
//
for(var i = 0; i < count; i++){
console.log(i); // 0, 1, ... count - 1
}
})();
console.log(i); // error
}
関数パッケージングでは、外部環境outputNumbers()の変数countにアクセスできます.0,1,…count-1を印刷しますが、関数パッケージングが完了したら、変数iにアクセスするとエラーが発生します.iは関数パッケージングで定義されていますので、outputNumbers()関数がアクセスできません.どこにいても、一時的な変数が必要な場合は、ブロックレベルのスコープを使用することができます.
このような関数パッケージングを使用すると、閉塞過多のメモリ占有の問題を減らすことができます.匿名関数への参照がないので、関数パッキンの実行が完了すれば、そのスコープは直ちに廃棄されます.
関数パッケーターという技術は、大域的な作用領域において関数の外部でよく用いられ、大域的な作用領域に過剰な変数と関数を追加することを制限する.一般的には、グローバルスコープに変数と関数を追加することは最小限にしなければなりません.多すぎるグローバル変数と関数は名前の衝突を招きやすいです.ブロックレベルのスコープを作成することで、各開発者は自分の変数を使うことができます.たとえば:
(function(){
var now = new Date();
if (now.getMonth() == 0 && now.getDate() == 1) {
console.log("Happy new year");
}
})();
このコードをグローバルスコープに置いて、いつが一月一日かを確認します.変数nowは、現在匿名関数におけるローカル変数であり、グローバル変数の作成を回避している.