javascriptの閉鎖
3189 ワード
浅談javascript閉包(closure)
クローズドはjs言語の一つの難点であり、その特色でもあり、多くの高級アプリケーションはクローズドによって実現されます.
一.変数のスコープ
クローズドを理解するには、まずjavascriptの特殊な変数のスコープを理解しなければならない.
変数のスコープには、大域変数と局所変数があります.
js言語の特殊な点は、関数内部で直接グローバル変数を読み込むことができることです.
たとえば:
様々な理由から関数内の局所変数を得る必要があります.しかし、前にも話しましたが、普通の状況ではできません.変通方法でしか実現できません.
それは関数の内部でもう一つの関数を定義することです.
f 2は、f 1の局所変数を読み出すことができるので、f 2を戻り値とすると、f 1の外部で内部変数を読み出すことができるのではないでしょうか?
上のコードのf 2関数がクローズドです.
一般的なクローズドの定義は非常に抽象的で、クローズドとは他の関数の内部変数を読み取る関数であることを私は理解しています.
js言語では、関数内部のワード関数だけが局所変数を読み取ることができるので、クローズドを単に「関数の内部に定義された関数」と理解することができます.
へへへ、たぶんカバンを閉じるということが分かりましたよね.
四、クローズドの用途
クローズドの用途は二つあります.一つは関数内部の変数を読み取ることができます.もう一つはこれらの変数の値を常にメモリに保存させます.へへへ、メモリに保存して、ちょっと新鮮でしょう.
どう理解しますか?次のように見てください.
どうしてですか?f 1はf 2の親関数であり、f 2はグローバル変数を与えられ、f 2は常にメモリ中にあり、f 2はf 1に依存しているため、f 1は常にメモリ中にあり、呼び出された後、ゴミ回収機構によって回収されない.
このコードのもう一つの注目すべき点は、「nAdd=function(){n+=1]」という行であり、まずnAddの前にvarキーワードが使用されていないため、nAddは局所変数ではなくグローバル変数である.第二に、nAddの値は匿名関数であり、この匿名関数自体もクローズドであるため、nAddは相当であり、関数の外部で関数内部の局所変数を操作することができる.
五、クローズドを使う注意点
1.クローズドは関数の変数をメモリに保存させますので、メモリの消耗が大きいので、クローズドを濫用してはいけません.そうでないと、ウェブページの性能問題が発生し、IEでメモリの漏洩を引き起こす可能性があります.解决方法は、関数を出す前に、使わない局部変数を削除することです.
2.親関数の外部で、親関数の内部変数の値を変更します.したがって、親関数を対象として使用する場合は、クローズドをそのパブリックメソッドとして、内部変数をそのプライベート属性として扱います.このときは、親関数の内部変数の値を勝手に変えないように注意してください.
まとめ:
クローズドとは、JavaのクラスAの宣言に相当する別のクラスBで、クラスBをクラスAのメンバー変数として使用し、クラスBの関数はクラスAの方法に相当します.クラスBの属性はプライベートです.クラスAはクラスBの属性を使用します.
--
第二編:
http://kb.cnblogs.com/page/110782/
後記:javaを学ばないと、Javascriptはどのようにクラス、クラスのメンバー変数、変数の作用領域、メンバー変数の作用領域、クラスの属性の継承とアクセス権限などの問題を処理しますか?
使用上の問題は同じです.呼び方が違うだけです.
を選択します.
クローズドはjs言語の一つの難点であり、その特色でもあり、多くの高級アプリケーションはクローズドによって実現されます.
一.変数のスコープ
クローズドを理解するには、まずjavascriptの特殊な変数のスコープを理解しなければならない.
変数のスコープには、大域変数と局所変数があります.
js言語の特殊な点は、関数内部で直接グローバル変数を読み込むことができることです.
たとえば:
var n = 9999;
function f1(){
alert(n);
}
f1();//9999
一方、関数の外部では当然、関数内部の局所変数を読み取ることができません.function f1(){
var n = 99;
}
alert(n); //
関数内部で変数を宣言する場合は、必ずvarコマンドを使用してください.使わないなら、実際にグローバル変数を宣言しました.function f1(){
n =99;
}
f1();
alert(n); //99
二.外部からローカル変数を読み取る方法様々な理由から関数内の局所変数を得る必要があります.しかし、前にも話しましたが、普通の状況ではできません.変通方法でしか実現できません.
それは関数の内部でもう一つの関数を定義することです.
fucntion f1(){
var n =99;
function f2(){
alert(n); //99
}
}
上のコードでは、関数f 2が関数f 1の内部に含まれており、f 1の内部のすべての局所変数は、f 2に対して可視である.しかし、逆にだめです.f 2の局部変数はf 1に対しては見えません.これはjs言語特有の連鎖作用ドメイン構造であり、サブオブジェクトはすべての親オブジェクトの変数を段階的に向上させます.したがって、親オブジェクトのすべての変数は、子オブジェクトに対しては見えますが、逆は成立しません.f 2は、f 1の局所変数を読み出すことができるので、f 2を戻り値とすると、f 1の外部で内部変数を読み出すことができるのではないでしょうか?
function f1(){
var n=99;
function f2(){
alert(n);
}
return f2;
}
var result = f1();
result(); //99
三.クローズドの概念上のコードのf 2関数がクローズドです.
一般的なクローズドの定義は非常に抽象的で、クローズドとは他の関数の内部変数を読み取る関数であることを私は理解しています.
js言語では、関数内部のワード関数だけが局所変数を読み取ることができるので、クローズドを単に「関数の内部に定義された関数」と理解することができます.
へへへ、たぶんカバンを閉じるということが分かりましたよね.
四、クローズドの用途
クローズドの用途は二つあります.一つは関数内部の変数を読み取ることができます.もう一つはこれらの変数の値を常にメモリに保存させます.へへへ、メモリに保存して、ちょっと新鮮でしょう.
どう理解しますか?次のように見てください.
function f1(){
var n =99;
nAdd = function(){n+=1;};
function f2(){
alert(n);
}
return f2;
}
var result = f1();
result();
nAdd();
result();
このコードの中で、resultは実はクローズドf 2関数です.全部で二回実行しました.一回目の値は99で、二回目の値は100です.これは関数f 1の部分変数がずっとメモリに保存されていて、f 1の呼び出し後に自動的にクリアされていないことを証明しています.どうしてですか?f 1はf 2の親関数であり、f 2はグローバル変数を与えられ、f 2は常にメモリ中にあり、f 2はf 1に依存しているため、f 1は常にメモリ中にあり、呼び出された後、ゴミ回収機構によって回収されない.
このコードのもう一つの注目すべき点は、「nAdd=function(){n+=1]」という行であり、まずnAddの前にvarキーワードが使用されていないため、nAddは局所変数ではなくグローバル変数である.第二に、nAddの値は匿名関数であり、この匿名関数自体もクローズドであるため、nAddは相当であり、関数の外部で関数内部の局所変数を操作することができる.
五、クローズドを使う注意点
1.クローズドは関数の変数をメモリに保存させますので、メモリの消耗が大きいので、クローズドを濫用してはいけません.そうでないと、ウェブページの性能問題が発生し、IEでメモリの漏洩を引き起こす可能性があります.解决方法は、関数を出す前に、使わない局部変数を削除することです.
2.親関数の外部で、親関数の内部変数の値を変更します.したがって、親関数を対象として使用する場合は、クローズドをそのパブリックメソッドとして、内部変数をそのプライベート属性として扱います.このときは、親関数の内部変数の値を勝手に変えないように注意してください.
まとめ:
クローズドとは、JavaのクラスAの宣言に相当する別のクラスBで、クラスBをクラスAのメンバー変数として使用し、クラスBの関数はクラスAの方法に相当します.クラスBの属性はプライベートです.クラスAはクラスBの属性を使用します.
--
第二編:
http://kb.cnblogs.com/page/110782/
後記:javaを学ばないと、Javascriptはどのようにクラス、クラスのメンバー変数、変数の作用領域、メンバー変数の作用領域、クラスの属性の継承とアクセス権限などの問題を処理しますか?
使用上の問題は同じです.呼び方が違うだけです.
を選択します.