【6】JavaScript関数が高度である.コンテキストと実行コンテキストスタック、変数のリフティング(図解+典型的な例分析)を実行する.


JavaScript関数は高級です.コンテキストと実行コンテキストスタック(図解+典型的な例分析)を実行します.
変数の昇格と関数の昇格
  • 変数宣言の昇格
  • は、 varによって定義された(ステートメント)変数によって、ステートメントを定義する前に
  • にアクセスすることができる.
  • 値:undefined
  • /*
          :    undefined
       */
    var a = 3
    function fn() {
        console.log(a) // undefined    fn()        ,   var        ,  undefined
        var a = 4
        console.log(a) // 4
    }
    fn()
    console.log('----')
    開発ツールのコードデバッグツールでブレークポイントを設定できます.aの値の変化.
  • 関数宣言の昇格
  • は、function によって宣言された関数によって、関数宣言の前に直接
  • を呼び出すことができる.
  • 値:関数定義(オブジェクト)
  • console.log(b) // undefined     var      b               
    fn2() // fn2()                  function      fn2        
    fn3() //                       var      fn3             
    
    var b = 3
    function fn2() {
      console.log('fn2()')
    }
    
    var fn3 = function () {
      console.log('fn3()')
    }
    !var a = 3var fn = function(){ }は、varによって宣言された限り、変数宣言の向上であり、値は全部undefinedである.
    !注意:var fn = function(){ }は変数宣言の昇格に属し、関数宣言の昇格ではありません.
  • 問題:変数アップと関数アップはどのように発生しますか?
  • これはJavaScriptで文脈の働き方を実行しているからです.関数と変数は、優先的に上昇します.これは関数がより前の位置に引き上げられることを意味する.JavaScriptは、初期化を向上させる代わりに、ステートメントのみを向上させます.
    コンテキストを実行
    コンテキスト個数=n(呼び出す関数個数)+1(グローバル実行コンテキスト)を実行します.
    //       ,      ,             Window      
    console.log(a1, window.a1) // undefined   undefined
    window.a2() // a2()
    console.log(this) // Window
    
    var a1 = 3
    function a2() {
        console.log('a2()')
    }
    console.log(a1) // 3
    コード分類(位置)
  • グローバルコード
  • 関数コード
  • グローバル実行コンテキスト
  • は、グローバルコードを実行する前に、windowをグローバル実行コンテキスト
  • として決定する.
  • は、グローバルデータを前処理する.
  • var により定義されたグローバル変数=>undefinedは、window属性
  • に追加されます.
  • functionによって宣言されたグローバル関数=>割当値(fun)は、windowに追加された方法
  • である.
  • this=>割当て(window)
  • は、グローバルコード
  • の実行を開始する.
    関数実行のコンテキスト
  • は、関数を呼び出し、関数を実行する前に、対応する関数を作成してコンテキストオブジェクト
  • を実行する.
  • は、ローカルデータを前処理する.
  • モダリティ変数=>赋値(実参)=>を実行コンテキストの属性として追加します.
  • arguments=>割当値(実際参照リスト)は、実行コンテキストの属性
  • として追加されます.
  • varで定義された局所変数=>undefined=>実行コンテキストの属性
  • に追加されます.
  • functionによって宣言された関数=>割当値(fun)=>実行コンテキストの属性
  • として追加されました.
  • this=>割当値(呼び出し関数のオブジェクト)
  • は、関数コード
  • の実行を開始します.
    コンテキストスタックを実行
    理解する
  • は、グローバルコードが実行される前に、 JSエンジンは、すべての実行コンテキストオブジェクト
  • を管理するスタックを作成する.
  • は、グローバル実行コンテキスト(window)の決定後、スタック(スタック)
  • に追加する.
  • は、関数実行コンテキスト作成後、スタック
  • に追加する.
  • は、現在の関数が実行された後、スタックトップのオブジェクトを除去する
  • .
  • すべてのコードが実行された後、スタックにはwindow
  • しか残っていません.
    プロセス分析
    // 1.        
    var a = 10
    var bar = function (x) {
        var b = 5
        // 3.   foo     
        foo(x + b)
    }
    var foo = function (y) {
        var c = 5
        console.log(a + c + y)
    }
    // 2.   bar       
    bar(10)  // 30
  • ブレークポイント調整ツールで実行コンテキストコールスタック
  • を確認する.
    面接問題
    タイトル1:再帰的に呼び出す実行コンテキスト
    console.log('gb: ' + i)  
    var i = 1
    foo(1)
    function foo(i) {
        if (i == 4) {
            return
        }
        console.log('fb:' + i)
        foo(i + 1) //    :          
        console.log('fe:' + i)
    }
    console.log('ge: ' + i) // ge:1
  • 順番に何を出力しますか?
  • 全体の過程でいくつかの実行コンテキストが発生しましたか?5 =4 +1
  • デバッグの表示:
    問題2:関数の昇格は変数の昇格より優先し、変数宣言によって上書きされませんが、変数の割当値によって上書きされます.
    console.log(foo)  // ƒ foo() {console.log("    ")}
    console.log(foo()) //         undefined
    function foo() {
      console.log('      ')
    }
    var foo = 3
    console.log(foo) // 3
    console.log(foo()) // foo is not a function
    に相当する
    function foo(){
        console.log("    ")
    }  //        
    var foo   //       ,        ,  foo   undefined,          
    console.log(foo)  //    ƒ foo() {console.log("    ")}
    console.log(foo()) //         undefined
    foo = 3 //    foo   3,       
    console.log(foo) // 3
    console.log(foo()) // foo is not a function,    foo=3
    問題3:グローバル環境を考察するときの変数のアップグレード
    if (!(t in window)) {
        var t = 1
    }
    console.log(t)  // undefined
    t in window
    // true
    その理由は、変数tがグローバル環境の最上部に引き上げられ、キーワードvarを介してグローバルスコープで宣言される変数がグローバルオブジェクトの属性として使用されることにあり、上のコードJavaScriptは、実際にはこのように解析される.
    var t
    if (!(t in window)) {
        var t = 1
    }
    console.log(t) // undefined
    問題4(いい問題)
    var c = 1
    function c(c) {
      console.log(c)
      var c = 3
    }
    c(2) //     c is not a function 
    注意:関数がc()に昇格し、関数全体が向上します.上のコードは下記のようになります.
    function c(c) {
        console.log(c)
        var c = 3
    }
    var c
    
    c = 1
    c(2) //   c is not a function
    関数のコードはまったく実行できません.