JS整理編:関数クローズドの私の理解


1、クローズドとは何ですか?他の関数の内部変数の関数を読み取ることができます.Javascript言語では、関数内部のサブ関数だけが局所変数を読み取ることができます.(内層作用領域は外層作用領域にアクセスできます.逆はダメです.)ので、クローズドを簡単に「関数の内部に定義された関数」と理解できます.したがって、本質的には、閉じたパケットは関数内部と関数外部をつなぐ橋です.
//     
function f1() {
  var num = 10
  num++
  return num
}
console.log(f1()) // 11
console.log(f1()) // 11
console.log(f1()) // 11

//       
function f2() {
  var num = 10
  return function () {
    num++
    return num
  }
}
var ff = f2() //                          :f2      
console.log(ff()) //11
console.log(ff()) //12
console.log(ff()) //13
局所変数は関数で、関数の使用が終わると、局所変数は自動的に解放されます.カプセル化後、内部の局所変数の使用はスコープチェーンを延長します. 
1.1  なぜクローズドを使うのですか? : グローバル変数と局所変数は、互換性のない優れた欠点を持っています.
  • グローバル変数: 優: 再利用可能です 欠落: 汚染されやすい
  • ローカル変数: 優: 関数内でのみ使用できます.汚染されません. 再利用不可!
  •   1.2  いつクローズドされますか?変数を再利用して、変数が汚染されないように保護する場合、どうやって使いますか?
  • 1.保護する変数と内部関数を外層関数で包む.
  • .外層関数は、内層関数を外部に返す.
  • .外層関数を呼び出し、内層関数を求めるオブジェクトは、外部の変数に保存されます.すなわち、クローズドされています.
  •   1.3 閉包が形成された理由: 外層関数の呼び出し後、外層関数の関数領域(AO)オブジェクトは解放されません.
  • AO参考:第19編js高級知識---品詞分析とAOチェーン
  • 2、閉包による問題:
           クローズドはいいですが、メモリ漏れなど一連の問題が発生しました.jsのゴミ回収メカニズムは参照数ですので、変数がもう使われなくなった時(参照は0と数えます.)ゴミ回収メカニズムはクリアされます.クローズドの存在は少なくとも1となります.(1.3を参照してください.) ).
    function f()
    {
       var myDiv = document.getElementById("Div1")
       myDiv.onclick = function()
       {
            console.log(myDiv.id)
       }
    }
           上記のコードの中で、関数fはmyDivをクリアする必要がありますが、myDivは匿名関数の存在により、少なくとも1の引用数です.したがって、使用されているメモリは永遠に回収されません.関数内の変数はメモリに保存されていますので、メモリの消耗が大きいので、パケットを乱用してはいけません.そうでないと、ウェブページの性能に問題が発生します.IEによる可能性があります.メモリが漏れる. 解決方法は、関数を終了する前に使用しないローカル変数をすべて削除します.
    function f()
    {
       var myDiv = document.getElementById("Div1")
       var id = myDiv.id
       myDiv.οnclick=function()
       {
            console.log(id)
       }
       myDiv = null
    }
           myDiv.idを変数の中に保存し、この変数をクローズドに引用することはmyDivとは関係ないが、クローズドは関数を含む活動対象全体を参照するので、myDivをnullとして参照を解除し、ゴミ回収メカニズムが資源回収できるようにしなければならない.
    何がクローズドですか?
    3、クローズド中のthis
           閉じたカバンの中でthisを使うと問題があります.大域関数の中でthisはwindowを指します.関数がメソッドに呼び出されると、thisはこのオブジェクトを指します.しかし、匿名関数の実行環境は大域的で、thisは普通windowを指します.ルビーの本の中の一つの経典的な問題を参照してください.
    var name = "The Window"
    var object = {
      name: "My Object",
      getNameFunc: function () {
        return function () {
          return this.name
        }
      }
    }
    
    console.log(object.getNameFunc()())  // "The Window"
            内部関数は、thisを検索すると、そのアクティブなオブジェクトだけが検索されます.匿名関数の実行環境は大域的なので、現在のアクティブなオブジェクトはwindowです.  現在のオブジェクトを変更することで、thisの方向を変更できます.
    var name = "The Window"
    var object = {    
      name: "My Object",
      getNameFunc: function () {
        var that = this
        return function () {
          return that.name
        }
      }
    }
    console.log(object.getNameFunc()())  // "My Object"
           ここではthisオブジェクトをthat変数に割り当てていますので、現在の活動対象はwindowからobjectになります.
     
    引用:
           C言語のような底の言語には、一般的にメモリ管理インターフェースがあります.例えばmalloc()free()があります.一方、JavaScriptは変数(対象、文字列など)を作成する時にメモリを割り当て、それらを使わない時には自動的にリリースします.後のプロセスはゴミ回収といいます.この「自動」は混乱の元です.JavaScriptは混乱の元です.(他の高級言語と)開発者はメモリ管理に関心を持たなくてもいいと思います.これは間違いです.