JS変数アップ

11159 ワード

変数アップとは?
まず、js実行前に「プリコンパイル」というプロセスがあり、プリコンパイルには主に二つのタスクがあります.
  • 全var変数(初期はundefined)を宣言します.
  • 解析定義式関数文.
  • つまり変数のアップグレードは、実際にjsのプリコンパイル段階で完了しました.
    変数アップの概念:関数と変数の宣言はjsのインタプリタによって一番上に置かれます.ES 6の前に、JavaScriptはブロックレベルのスコープがありません.グローバルスコープと関数スコープだけがあります.
    変数の昇格
  • 栗1
  • 	function fn1() {
          a = 1;
          console.log(a); 
          console.log(window.a); 
          var a = 5;
          console.log(a); 
        }
        fn1();
    
    出力結果は順次1 undefined 5となります.コードは解析時に相当します.
    	  var a;//              ,    ,     ,     a undefined
     	  a = 1;
          console.log(a); 
          console.log(window.a); //           a,           a
          a = 5;
          console.log(a); 
    
  • 栗2
  • 	function fn1() {
          console.log(a); // a is not defined
          a = 5;
          console.log(a); //        ,  5
        }
        fn1();
    
    変数のアップグレードは、var xx=5などの変数宣言のプロセスが必要です.上の栗のようにaに直接対価すると宣言しないと、aは全体の対象となります.変数の昇格は存在しません.だから最初のコンサートは間違えます.
  • 栗3
  • 	//      
    	a = 5;
    
    	//      
    	var a = 5;
    
    すべてのグローバルスコープで実行されます.両端のコードには何の違いがありますか?
  • a=1はwindow.a=5に相当します.グローバルwindowオブジェクトに属性a値を追加しました.5
  • var a=5は、グローバルスコープで変数aを宣言したのに相当し、全域で有効
  • 後者は前者より一つ多い声明の行為
  • 前者は変数アップの過程がなく、事前に訪問した場合にエラーが発生し、後者は変数アップ
  • 栗4
  • function fn2(){
    	console.log(a);//undefined
    	if(true){
    		var a = 10;
    	}
    	console.log(a);//10
    }
    
    この栗の中で、a変数の声明も同じく引き上げられました.だからifは機能領域がないのです.関数だけがスコープを持っています.(forサイクルなども同じです)
    関数の昇格
    jsには関数を定義する方法が二つあります.
  • 関数式var fn=function fn(){}
  • 関数宣言方式は、定義式function fn(){}
  • 関数が関数宣言によって定義されると、関数が向上します.
  • 変数の上昇中、変数の割当値が引き上げられていません.
  • しかし、関数アップはちょっと違っていて、関数体も一緒に向上されます.
  • test();
    
    function test(){
    	console.log(1);
    }
    
    したがって、上記のような場合は、先にtest関数を実行してから声明しますが、実際には関数が実行されています.これは変数のアップグレードとは異なる点です.関数のアップグレードは声明のアップグレードだけではなく、関数も一緒にアップグレードされます.
  • 関数表現によって作成された関数は声明だけアップされ、関数体はアップグレードされないので注意する
  • fn3();//fn3 is not a function
    
    var fn3 = function(){}
    
    二つの例を見てください.
    function bar() {
    	console.log('bar1')
    }
    
    var bar = function () {
    	console.log('bar2')
    }
    
    bar()
    
    2:
    var bar = function () {
    	console.log('bar2')
    }
    
    function bar() {
    	console.log('bar1')
    }
    
    bar()
    
    結果はすべてbar 2を出力し、プリコンパイル段階では変数barは声明しますが、値は与えられません.関数barを作成してアップグレードします.運転段階barには値が割り当てられます.
    補足——SE 6の変数アップ
    es 6にブロックレベルのスコープが追加され、letおよびconst宣言の変数はブロックレベルのスコープを発生する.また、letとconst宣言の変数は変数のアップグレードをしません.だから、一時的な死区が現れます.
    foo(10)
    function foo(num) {
    	//      
        console.log(foo)
        //      
        let foo = num
    }
    
    この場合、ブラウザのエラーfoo is not defined.これはletとconst宣言の変数が変数のアップグレードをしないため、変数の宣言と割当値はいずれもconsolone.logsの後にあるので、訪問は存在しません.