預編譯是JS語言的難點重點之一,難點在於不便理解,重點在於必須掌握。javascript
預編譯實際上就是JS引擎的兩次掃描,第一次掃描是檢測聲明,第二次掃描是執行代碼。java
預編譯分爲腳本的預編譯和函數調用的預編譯,先來講說腳本的預編譯。git
1.建立全局對象GO(GlobalObject)github
2.加載腳本文件函數
3.預編譯:ui
4.解析執行代碼spa
1.沒有var的變量,都不是變量聲明,所有認爲是window的全局變量,不參與預編譯。code
// console.log(aa); // Uncaught ReferenceError: aa is not defined
aa = 5;
console.log(aa); // 5
複製代碼
2.即便在函數中,aa也是全局變量。(運行時)cdn
test();
function test() {
aa = 5;
}
console.log(aa); // 5
複製代碼
3.腳本中的全部聲明變量,在腳本預編譯階段完成,全部變量的聲明與實際書寫位置無關。對象
console.log(aa); // undefined
var aa = 5;
console.log(aa); // 5
複製代碼
4.腳本中的全部函數聲明,在腳本預編譯階段完成,全部函數聲明與實際書寫位置無關。
console.log(hh); // f hh(){...}
function hh() {
console.log('hh');
}
複製代碼
5.腳本中,若是變量與函數同名,那麼將覆蓋變量。
console.log(haha); // f haha(){...}
var haha = 123;
function haha() {
console.log(2333);
}
複製代碼
6.腳本中,只有函數可以覆蓋變量,可是變量沒法覆蓋函數。(注意: 函數優先級大於變量!)
console.log(haha); // f haha(){...}
function haha() {
console.log(2333);
}
var haha = 123;
複製代碼
7.腳本中,後面的函數聲明會覆蓋前面的函數聲明,而且忽略參數。
haha(1); // 'haha2'
function haha(a) {
console.log('haha1');
}
function haha(b,c) {
console.log('haha2');
}
複製代碼