js声明を深く理解して上げます.

4701 ワード

javaScriptは上から下まで実行する順序は多くの新米と一部のベテランの共通認識を受けていますが、これは完全に正確ではありません.これはjsのコンパイル過程に関連しています.この点は後で下記のコードを考慮します.
window.onload = function(){
    xxx.onclick = fn;
};
function fn() {...}
あなたのコードにはこのような書き方が存在していますか?完全にトップダウンで成立すれば、このように書くのは間違いがあるはずです.Oload関数はページの読み込みが終わった後に実行します.jsは先に下記のコードをロードしていますので、大丈夫です.
しかし、実際にはOloadも関数だけで、関数がトリガした時間と一般の関数は違っています.本質的には普通の関数と区別されていません.コンパイラは相変わらずロードして、このエラーは依然としてエラーを報告します.この問題の本質は「関数の向上」です.
関数の「昇格」挙動を理解するには、jsの「昇格」とは何かを先に解析しましょう.
1.昇格
jsのコードは生成前にコードをコンパイルします.コンパイルの一部の作業はすべての声明を見つけることです.そして、作用領域を確立してそれを関連付けるので、現在のスコープ内に変数と関数を含むすべての声明は任意のコードが実行される前に処理されます.
ここでは「声明」が先に処理されますが、割り当てはされていません.定義文はコンパイル段階で行われます.つまり声明は昇格されました.賦課はまだ元の場所に残っています.執行を待っています.
2.変数の昇格
下記のコードを考慮して、予想出力結果:
 console.log(a);
 var a = 2;
に等しい
 var a ;         // a    undefined
 console.log(a); // undefined
 a = 2;
ここでは上の結論文を使って昇格させました.賦課は元の場所に残しています.
2.1.関数式
 a();     //typeError a    
 var a = function(){...};
関数式の昇格==変数の昇格(違いは変数の種類)ですが、名前がコロコロとしていて、すぐに私たちが話したい関数の昇格と混同しやすいです.
簡単な方法で関数式かそれとも関数かを判断します.Fnctionキーワードは声明全体の最初の単語であれば関数です.そうでなければ関数式です.
console.log(a); // ReferenceError  a is not defined
+function a(){ console.log(1); } //function      
3.関数アップ
関数の昇格と変数の昇格は共に向上されますが、重要な詳細があります.関数の優先度が一番高いので、まず上げられます.
下記のコードを考慮します
foo();
function foo(){ console.log(1); }
var foo = function(){ console.log(2); }
foo();
に等しい
var foo ;  //         
function foo(){ console.log(1); }

foo(); //1

foo = function(){ console.log(2); }

foo(); //2
4.まとめ
1.                ,              ,         。

2.      ,                       ,          。

5.面接問題の解析
(問題の最後の答え+詳細解析)
ネット上の3タイトルを選んだのは難しいです.迷っている人が多い面接問題:
1.
console.log(foo);     // ?
console.log(bar);     // ?

var foo = function(){...}; 
function bar(){...} 
==============================================================================================================================================================================
答え:undefined,function bar(){…}
詳細:
var foo ;
function bar(){...} 

console.log(foo);    // undefined 
console.log(bar);    // function bar(){...}

foo = function(){...}; 
上のコードは分かりやすいです.本題は関数と関数式の違いです.変数宣言と関数は先に上部に上げて、その場所に割り当てられます.fooはデフォルトのundefinedです.barは関数自体を出力します.
2.
function foo(){
    a = 5;
    console.log(window.a);  //  ?
    console.log(a);         //  ?
    var a = 10;
    console.log(a);         //  ?
}
foo();
==============================================================================================================================================================================
答え:undefined、5、10
詳細:
ここでは、グローバル汚染問題、すなわちvarまたは他の宣言キーワードを使用して声明に出ない場合、本作用領域で声明が見つからない場合、最上階のグローバルwindowに接続されるまで、デフォルトで上位の者に探す(厳格なモードレポートnot defined).たとえば:
function foo(){
    a = 1;
    console.log(window.a);    // 1   a       
}
foo();
次は本題の解析です.ポイントは全体の汚染と向上です.
function foo(){
    var a ;                   //        a  ,a     
    a = 5;                    //           a     ,a        ,
                              //          a ,           
    console.log(window.a);    // undefined 
                              //a = 5       ,  window.a   ,   undefined
    console.log(a);           // 5 ,a      ,   a = 10     ,a      5
    a = 10;
    console.log(a);           // 10
}
foo();
3.
function foo() {
   var a = 1;        
   function b() {   
      a = 10;
      return '';
      function a() {...}
    }
    b();
    console.log(a);         // ?
}
foo();
==============================================================================================================================================================================
3いいえ、大丈夫です
詳細:試験点1.汚染2.3.作用域の向上
function foo() {
    var a ;                    // a   b           
    
    function b() {
      function a() {...}      //b    a    b   
      a = 10;                 //       a,  a         ,     a      
                              //      ,    a    10,     
      return '';
    }
    
    a = 1;                    //      a  
    
    b();                      //    ,b     a    10
    console.log(a);           // 1
                              //           :
                              // 1. b a          
                              // 2.     ,    log(a)       a  ,
                              //  log   b ,            10
}
foo();
参考書:知らないJavaScripptKYLE SIMPON著(オススメ)