閉パッケージ+同期タスク+非同期タスクの興味深い小question

6284 ワード

question 1:需要を与える:需要:あるボタンをクリックし、「クリックしたのはn番目のボタン」を提示する



    
        
        00_ 
    

    

        
        
        
        
            var btns = document.getElementsByTagName('button')
            // 
            for (var i = 0,length=btns.length; i < length; i++) {
                  var btn = btns[i];
                  btn.onclick = function () {
                    console.log(' '+(i+1)+' ')
                  }
            }
        



すみません、この書き方はどうして間違っていますか?buttonがクリックされると何が印刷されますか?
   :" 4 "
 > ,for , dom , i=3

同じ需要を増やして、少し変えて、このようにしますか?
for (var i = 0,length=btns.length; i < length; i++) {
              var btn = btns[i]
              // btn btn 
              btn.index = i;
              btn.onclick = function () {
                alert(' '+(this.index+1)+' ')
              }
}

結果:
 btn alert 1, btn alert 2, btn alert 3
 , btn , btn.index btn.a, , 

question 2:これは比較的古典的な閉鎖面接問題です.

            // 
            var name = "The Window";
            var object = {
                name: "My Object",
                getNameFunc: function() {
                    return function() {
                        return this.name;
                    };
                }
            };
            console.log(object.getNameFunc()()); 
            //  the window

            // 
            var name2 = "The Window";
            var object2 = {
                name2: "My Object",
                getNameFunc: function() {
                    var that = this;
                    return function() {
                        return that.name2;
                    };
                }
            };
            console.log(object2.getNameFunc()()); 
            //  myobject
            
        

question 3:閉包関連の面接問題でもあり、少し遠回りしました.
function fun(n, o) {
                console.log(o);
                return {
                    fun: function(m) {
                        return fun(m, n)
                    }
                }
            }
            var a = fun(0);
            // undefined
            a.fun(1);
            //0;
            a.fun(2);
            //0
            a.fun(3);
            //0
            var b = fun(0).fun(1).fun(2).fun(3);
            //  undefined 0 1 2 
            
            var c = fun(0).fun(1)  //  undefined 0
            c.fun(2) //1 
            c.fun(3) //1

どのようにして閉パッケージを生成しますか?


ネストされた内部(サブ)関数がネストされた外部(親)関数の変数(関数)を参照すると、閉パケットが生成されます.

閉鎖はいったい何ですか。

  • chromeデバッグを使用して
  • を表示
  • 理解一:閉パケットはネストされた内部関数(ほとんどの人)
  • である
  • 理解二:参照変数(関数)を含むオブジェクト(ごく少数)
  • 注:閉包はネストされた内部関数に存在する
  • 閉パッケージを生成する条件は?

  • 関数ネスト
  • 内部関数外部関数のデータ(変数/関数)
  • を参照
    // 1.  
                function fn1() {
                    var a = 2
    
                    function fn2() {
                        a++
                        console.log(a)
                    }
                    return fn2
                }
                var f = fn1()
                f() // 3
                f() // 4
    

    クローズド・パッケージ内で参照される変数は、ゴミとして回収されません.

    クローズドパッケージの役割?

  • 関数内部の変数を使用して、関数の実行後もメモリに残ります(ローカル変数のライフサイクルが延長されます)
  • .
  • 関数外部が関数内部に操作(読み書き)できるようにするデータ(変数/関数)問題:
  • 関数の実行後、関数内部で宣言されたローカル変数はまだ存在しますか?一般に存在しないが、閉に存在する変数は
  • しか存在しない.
  • 関数外部で関数内部のローカル変数に直接アクセスできますか?いいえ、パッケージを閉じて外部に操作することができます.
  • 
                function fn1() {
                    var a = 2
                    function fn2() {
                        a++
                        console.log(a)
                        // return a
                    }
                    function fn3() {
                        a--
                        console.log(a)
                    }
                    return fn3
                }
                var f = fn1()
                f() // 1
                f() // 0
    
    

    閉じたライフサイクル

  • 生成:ネスト内部関数定義の実行が完了すると(呼び出しではない)
  • が生成される.
  • 死亡:ネストされた内部関数がゴミオブジェクトになったとき
  • 
      function fn1() {
        // ( ,  )
        var a = 2
        function fn2 () {
          a++
          console.log(a)
        }
        return fn2
      }
      var f = fn1()
      f() // 3
      f() // 4
      f = null // ( )
    
    

    閉パッケージの適用-カスタムjsモジュール


    閉パッケージの適用2:JSモジュールの定義
  • 特定の機能を有するjsファイル
  • すべてのデータと機能を1つの関数の内部(プライベート)
  • にカプセル化する
  • は、1つのパケット信号n個の方法のオブジェクトまたは関数
  • のみを外部に露出する.
  • モジュールの使用者は、モジュールが露出するオブジェクト呼び出し方法によって対応する機能
  • を実現するだけである.
    2つの方法があります.まず最初の方法を紹介します.
    
    
      var module = myModule()
      module.doSomething()
      module.doOtherthing()
    
    

    myModule.jsの内容:
    unction myModule() {
      // 
      var msg = 'My atguigu'
      // 
      function doSomething() {
        console.log('doSomething() '+msg.toUpperCase())
      }
      function doOtherthing () {
        console.log('doOtherthing() '+msg.toLowerCase())
      }
    
      // ( )
      // , , 
      return {
        doSomething: doSomething,
        doOtherthing: doOtherthing
      }
    }
    

    2つ目のメソッドは、即時実行関数を使用し、2つ目のメソッドを使用することを推奨します.myModule()を1回実行する必要はありません.
    
    
      myModule2.doSomething()
      myModule2.doOtherthing()
    
    

    myModule2.js:
    (function () {
      // 
      var msg = 'My atguigu'
      // 
      function doSomething() {
        console.log('doSomething() '+msg.toUpperCase())
      }
      function doOtherthing () {
        console.log('doOtherthing() '+msg.toLowerCase())
      }
    
      // ( )
      window.myModule2 = {
        doSomething: doSomething,
        doOtherthing: doOtherthing
      }
    })()
    

    クローズドパッケージの欠点と解決

  • 欠点
  • 関数の実行後、関数内のローカル変数は解放されず、メモリ消費時間が
  • 長くなります.
  • メモリの漏洩が発生しやすい
  • 解決
  • 閉鎖せずに
  • を使用できます.
  • タイムリーリリース