違いは次のとおりです: 1. JavaScript のクロージャは実際には関数内で定義された関数です (子関数であるため、親関数の内部変数を読み取ることができます); 2. Java のクロージャメソッドは変数として保存され、このメソッドはクラスの自由変数にアクセスする機能を持ちます。
このチュートリアルの動作環境: Windows7 システム、JavaScript バージョン 1.8.5、Dell G3 コンピューター。
1. Javascript でのクロージャ:
1. 変数のスコープ
必須クロージャを理解するには、まず Javascript の特殊な変数スコープを理解する必要があります。
変数のスコープには、グローバル変数とローカル変数の 2 種類があります。
Javascript 言語の特別な点は、グローバル変数を関数内で直接読み取ることができることです。
var n=999; function f1(){ alert(n); } f1(); // 999
一方、関数内のローカル変数は関数の外から読み取ることができません。
function f1(){ var n=999; } alert(n); // error
ここで注意すべき点が 1 つあり、関数内で変数を宣言する場合は、var コマンドを使用する必要があります。これを使用しない場合、実際にはグローバル変数を宣言していることになります。
function f1(){ n=999; } f1(); alert(n); // 999
2. 外部からローカル変数を読み取る方法
さまざまな理由により、関数内でローカル変数を取得する必要がある場合があります。ただし、前述したように、これは通常の状況では不可能であり、回避策によってのみ実現できます。
つまり、関数内に別の関数を定義します。
function f1(){ n=999; function f2(){ alert(n); // 999 } }
f2 は f1 のローカル変数を読み取ることができるため、f2 が戻り値として使用される限り、f1 の外部でその内部変数を読み取ることはできません。
function f1(){ n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999
3. クロージャの概念
上記の f2 関数はクロージャです。クロージャは実際には関数内で定義された関数です (子関数であるため、親関数の内部変数を読み取ることができます)。
本質的に、クロージャは関数の内部と関数の外部を接続する橋です。
4. クロージャの目的
1. 関数内の変数を読み取ることができます。
2. これらの変数を (クロージャによって参照されます)変数の値は常にメモリに保持されます。
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000
このコードでは、result は実際にはクロージャ f2 関数です。これは 2 回実行され、1 回目の値は 999、2 回目の値は 1000 でした。これは、関数 f1 のローカル変数 n が常にメモリに格納され、f1 が呼び出された後に自動的にクリアされないことを証明します。
なぜそうなるのでしょうか?その理由は、f1 が f2 の親関数であり、f2 がグローバル変数に割り当てられているため、f2 は常にメモリ内に存在し、f2 の存在は f1 に依存するため、f1 は常にメモリ内にあり、削除されないためです。呼び出しが完了すると、ガベージ コレクション メカニズム (ガベージ コレクション) によってリサイクルされます。
このコードでもう 1 つ注目すべき点は、「nAdd=function(){n =1}」という行です。まず第一に、var キーワードは nAdd の前に使用されていないため、nAdd はグローバル変数です。ローカル変数よりも。次に、nAdd の値は匿名関数であり、匿名関数自体もクロージャであるため、nAdd は関数の外部で関数内のローカル変数を操作できるセッターと同等です。
5. クロージャ使用時の注意点
1. クロージャは関数内の変数をメモリ上に格納するため、メモリ消費量が非常に多くなります。クロージャを乱用しないでください。
2. クロージャは、親関数内の変数の値を親関数の外で変更します。
6. クロージャの適用シナリオ
1. 関数内の変数を保護します。最初の例を例にとると、関数 a の i には関数 b によってのみアクセスでき、他の手段ではアクセスできないため、i のセキュリティは保護されます。
2. 変数をメモリ内に保持します。前の例と同様に、クロージャにより、関数 a の i は常にメモリ内に存在するため、c() が実行されるたびに、i は 1 ずつインクリメントされます。
# 2. Java でのクロージャ
##1. Java でのクロージャの定義## 定義: クロージャはメソッドを変数として保存でき、このメソッドはクラスの自由変数にアクセスする機能を持ちます。
Java 言語自体は正式にはクロージャをサポートしていませんが、クロージャ (内部クラス インターフェイス) のシミュレーションは可能です。クロージャは、匿名の内部クラスを使用して実装できます。 この普通のオブジェクトがそのクラスの自由変数にアクセスできるようにするにはどうすればよいでしょうか?インナークラス。内部クラスは、外部クラスのすべてのプロパティとメソッドにアクセスできます。 特定の実装を隠すことは内部クラスの機能の 1 つですが、特定の実装を隠しながらクロージャを外部使用に確実に渡すにはどうすればよいでしょうか?内部クラスに共通インターフェイスを実装させ、内部クラス オブジェクトをインターフェイス型にアップキャストします。 2. 単純なコード実装:public final static String name = "纯牛奶";// 名称 private static int num = 16;// 数量 public Milk() { System.out.println(name + ":16/每箱"); } /** * 闭包 * * @return 返回一个喝牛奶的动作 */ public Active HaveMeals() { return new Active() { public void drink() { if (num == 0) { System.out.println("木有了,都被你丫喝完了."); return; } num--; System.out.println("喝掉一瓶牛奶"); } }; } /** * 获取剩余数量 */ public void currentNum() { System.out.println(name + "剩余:" + num); } } /** * 通用接口 */ interface Active { void drink(); } //闭包的使用 public class Person { public static void main(String[] args) { //买一箱牛奶 Milk m = new Milk(); Active haveMeals = m.HaveMeals(); //没事喝一瓶 haveMeals.drink(); //有事喝一瓶 haveMeals.drink(); //看看还剩多少? m.currentNum(); } }
1. クロージャは実際のプロジェクトではあまり使用されません。だから彼の資質についてはコメントできない。
2. クロージャは合理的に使用し、完全に使用したり乱用したりしないことをお勧めします。
3. 特別な注意: クロージャによりリソースがリサイクルされなくなります。上記の例のように、main メソッドで m を null に設定し、haveMeals を使用してドリンク メソッドの呼び出しを継続しても、ボトルのボトルを飲み続けます。 Milk は、Milk オブジェクトが解放されていないことを示します。
[推奨学習:JavaScript 上級チュートリアル]
以上がJava クロージャと JavaScript クロージャの違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。