1。閉鎖とは何ですか
閉鎖とは、別の関数範囲で変数にアクセスする許可を持つ関数です。
簡単に言えば、JavaScriptは内部関数、つまり関数定義と関数式の使用を別の関数の関数本文に使用できます。さらに、これらの内部関数は、すべてのローカル変数、パラメーター、およびそれらが存在する外部関数で宣言されたその他の内部関数にアクセスできます。これらの内部関数のいずれかがそれらを含む外部関数の外部で呼び出されると、閉鎖が形成されます。
2。変数の範囲
閉鎖を理解するには、まず変数の範囲を理解する必要があります。
変数には、グローバル変数とローカル変数の2種類のスコープのみがあります。
JavaScript言語の特別な特徴は、グローバル変数を関数内で直接読み取ることができることです。
内部関数のスコープチェーンには外部関数の範囲が含まれているため、外部関数の変数に内部関数にアクセスできます。
また、以下として理解することもできます。内部関数の作用範囲は、外部関数の作用範囲に放射されます。
var n = 999; function f1(){alert(n);} f1(); // 999一方、関数内のローカル変数は、当然関数の外側で読み取られません。
function f1(){var n = 999;} alert(n); // エラーここに注意する場所があります。変数を内部的に宣言する場合は、VARコマンドを使用する必要があります。そうでない場合は、実際にグローバル変数を宣言します!
関数f1(){n = 999;} f1(); alert(n); // 9993.閉鎖を書き、使用するいくつかの方法
3.1。関数にいくつかのプロパティを追加します
関数円(r){this.r = r; } circle.pi = 3.14159; circle.prototype.area = function(){return circle.pi * this.r * this.r; } var c = new Circle(1.0); alert(c.area()); //3.141593.2。変数を宣言し、値として変数に関数を割り当てます。
var circle = function(){var obj = new object(); obj.pi = 3.14159; obj.area = function(r){return this.pi * r * r; } objを返します。 } var c = new Circle();アラート(c.area(1.0)); //3.141593.3。この方法はより頻繁に使用され、最も便利です。 var obj = {}は空のオブジェクトを宣言することです
var circle = {"pi":3.14159、 "area":function(r){return this.pi * r * r; }};アラート(circle.area(1.0)); // 3.141594.閉鎖の主な機能
閉鎖は多くの場所で使用できます。 2つの最大の用途があります。1つは、関数内の変数を上記のように読み取ることができ、もう1つはこれらの変数の値が常にメモリに保持されることです。
4.1。外部からローカル変数を読む方法は?
さまざまな理由で、関数内でローカル変数を取得する必要がある場合があります。ただし、前述のように、通常の状況では、これは実行できず、回避策によってのみ達成できます。
それは、関数内の別の関数を定義することです。
関数f1(){var n = 999; function f2(){alert(n); // 999}}上記のコードでは、関数F2が関数F1内に含まれており、F1内のすべての局所変数がF2に表示されます。しかし、逆の方法は不可能です。 F2内のローカル変数は、F1には見えません。これは、JavaScript言語に固有の「チェーンスコープ」構造です。子オブジェクトは、すべての親オブジェクト変数のレベルごとに上向きに見えます。したがって、親オブジェクトのすべての変数が子オブジェクトに表示されます。そうしないと、それは真ではありません。
F2がF1のローカル変数を読み取ることができるため、F2が戻り値として使用される限り、F1以外の内部変数を読むことはできませんか?
関数f1(){var n = 999; function f2(){alert(n); } return f2;} var result = f1(); result(); // 9994.2。メモリ内の変数の値を常に保存する方法は?
関数f1(){var n = 999; nadd = function(){n+= 1} function f2(){alert(n); } return f2;} var result = f1(); result(); // 999Nadd(); result(); // 1000このコードでは、結果は実際には閉鎖F2関数です。合計で2回実行され、最初の値は999、2番目の値は1000です。これは、関数F1のローカル変数nがメモリに保持され、F1が呼び出された後に自動的にクリアされないことを証明しています。
なぜこれが起こっているのですか?その理由は、F1がF2の親機能であり、F2がグローバル変数に割り当てられ、F2が常にメモリになり、F2の存在はF1に依存するためです。したがって、F1は常にメモリにあり、コールが終了した後、ゴミ収集メカニズムによってリサイクルされません。
このコードのもう1つの注目すべき点は、「nadd = function(){n+= 1}」という行が最初にNADDの前に使用されるため、NADDはローカル変数ではなくグローバル変数であることです。第二に、NADDの値は匿名関数であり、この匿名関数自体も閉鎖であるため、NADDは関数の外側の関数内のローカル変数で動作するセッターと同等です。
5。閉鎖とこのオブジェクト
閉鎖でこのオブジェクトを使用すると、いくつかの問題が発生する可能性があります。匿名関数の実行はグローバルであるため、このオブジェクトは通常ウィンドウを指します。コードは次のとおりです。
var name = "the window"; var object = {name: "my object"、getnamefun:function(){return function(){return this.name;};}}; alert(object.getnamefun(){}); //「ウィンドウ」(非ストリクトモード)このオブジェクトは、閉鎖によってアクセスできる変数の外部スコープに保存すると、閉鎖はオブジェクトにアクセスできます。コードは次のとおりです。
var name = "the Window"; var object = {name: "my object"、getnamefun:function(){var that = this; return function(){return that.name;};}}; alert(object.getnamefun(){}); //「私のオブジェクト」6。閉鎖とメモリの漏れ
具体的には、HTML要素が閉鎖の範囲に保存されている場合、要素を破壊できないことを意味します。次のように:
function assignhandler(){var element = document.getElementbyId( "someElement"); element.onclick = function(){alert(element.id);}}}上記のコードは、Element Elementイベントハンドラーとして閉鎖を作成し、この閉鎖は円形の参照を作成します。匿名関数は、AssignHandler()のアクティブなオブジェクトへの参照を保存するため、要素への参照の数を減らすことはできません。匿名関数が存在する限り、要素への参照の数は少なくとも1であるため、それが占めるメモリはリサイクルされません。
コードを書き換えることにより、内部リサイクルの問題を解決します。
function assignhandler(){var element = document.getElementById( "someElement"); var id = element.id; element.onclick = function(){alert(id);} element = null;}上記のコードでは、実装の閉鎖は要素を直接参照せず、関数を含むアクティブオブジェクトに参照が引き続き保存されます。したがって、要素変数をnullに設定して、それが占めるメモリを正常にリサイクルできるようにする必要があります。
7。閉鎖の使用に関するメモ
1)閉鎖は関数のすべての変数をメモリに保存し、メモリ消費量が非常に大きく、閉鎖は乱用できないため、Webページのパフォーマンスの問題を引き起こし、IEでメモリ漏れにつながる可能性があります。解決策は、関数を終了する前に使用されないすべてのローカル変数を削除することです。
2)閉鎖により、親関数の外側の親関数内の変数の値が変更されます。したがって、親関数をオブジェクトとして使用する場合、クロージャーをパブリックメソッドとして使用し、内部変数を私有地として使用します。親関数の内部変数の値をWELで変更しないように注意してください。
上記は、編集者が紹介したJavaScriptの閉鎖の執筆と機能の詳細な説明です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!