標籤:fun 錯誤 函數 包含 alert bsp 原因 提升 載入
本文部分內容轉自https://www.cnblogs.com/CBDoctor/p/3745246.html
1.變數提升
1 console.log(global); // undefined 2 var global = ‘global‘; 3 console.log(global); // global 4 5 function fn () { 6 console.log(a); // undefined 7 var a = ‘aaa‘; 8 console.log(a); // aaa 9 }10 fn();
疑問一:
還沒有定義a和global,為什麼就變成了undefined呢?
2.函數提升
1 console.log(f1); // function f1() {} 2 console.log(f2); // undefined 3 function f1() {}4 var f2 = function() {}
疑問二:
console.log(f1)為什麼能夠輸出還未定義初始化的f1函數呢?
疑問三:
類似於疑問一,為什麼f2還沒定義,就輸出undefined呢?
這些疑問的答案,都來自JS的先行編譯機制:
3.先行編譯
JS並不會完全按照代碼順序進行解析執行,而是在解析之前進行一次“先行編譯”。在此過程中,會把:
(1)定義式的函數優先執行
(2)所有var變數定義,預設值為undefined
這就解釋了上面兩段代碼輸出的原因了,上面的兩段代碼我們可以用下面的形式理解:
變數提升:
1 var global; 2 console.log(global); // undefined 3 global = ‘global‘; 4 console.log(global); // global 5 6 function fn () { 7 var a; 8 console.log(a); // undefined 9 a = ‘aaa‘;10 console.log(a); // aaa11 }12 fn();
函數提升:
1 function f1() {}2 var f2;3 console.log(f1); 4 console.log(f2); 5 f2 = function() {}
4.容易出錯的一點
1 // 調用函數,傳回值1 2 f(); 3 function f(){ 4 alert(1); 5 } 6 7 // 調用函數,返回語法錯誤。 8 f(); 9 var f = function(){10 alert(1);11 }
這個一看就懂為啥了,在先行編譯階段,聲明了變數f,而沒有為它賦值(匿名函數)。直接調用,肯定出錯。
5.總結
JS載入包含先行編譯和執行兩個階段。 編譯階段會對所有的var變數和function進行掃描,並將var變數初始化為undefined類型,而function則被初始化為函數值。
到了執行階段,JS從上面往下面依順序執行,遇到var變數便進行賦值(因此,在賦值之前進行調用的話會出現錯誤).遇到函數變數的話會從使用中的物件中尋找函數
JavaScript 先行編譯(變數提升和函數提升的原理)