一:函數聲明與函數定義表達式在函數調用間的區別
<script type="text/javascript">
doA();
var doA = function(argument) {
console.log('執行了')
}
</script>
結果:
<script type="text/javascript">
doA();
function doA(argument) {
console.log('執行了')
}
</script>
結果:執行了
結論:函數聲明在編譯期處理了函數聲明,但是函數定義表達式並沒有初始化與賦值。類似聲明瞭一個變量,但是變量沒有賦值。
二:多個script
之間對於變量的關係
JS是按照代碼塊來進行編譯和執行的,代碼塊間相互獨立,但變量和方法共享。
<script type="text/javascript">
function doA(argument) {
console.log('執行了')
}
</script>
<script type="text/javascript">
doA();
</script>
結果:執行了
**如果兩個函數塊之間更換位置,那就會報錯。
<script type="text/javascript">
var a = 0;
</script>
<script type="text/javascript">
console.log(a);
</script>
結果:0
**如果兩個函數塊之間更換位置,那就會報錯。
三:這樣就造成了一個問題,當我們一個頁面中引入多個js的時候,可能會造成全局變量的污染。
我們可以這麼做來避免:
<script type="text/javascript">
var a = 0;
</script>
<script type="text/javascript">
;(function(){
var a = 1;
console.log(a);
})();
console.log(a);
</script>
結果:1
0
或者我們直接用函數來做:
<script type="text/javascript">
function bigDoA(argument) {
var a = 0;
//其他代碼
}
</script>
<script type="text/javascript">
function bigDoB(argument) {
var a = 0;
//其他代碼
}
</script>
javaScript
解釋器在執行腳本時,是按塊來執行的。通俗地說,就是瀏覽器在解析HTML文檔流時,如果遇到一個<script>
標籤,則JavaScript
解釋器會等到這個代碼塊都加載完後,先對代碼塊進行預編譯,然後再執行。執行完畢後,瀏覽器會繼續解析下面的HTML文檔流,同時JavaScript
解釋器也準備好處理下一個代碼塊。
雖然說,JavaScript
是按塊執行的,但是不同塊都屬於同一個全局作用域,也就是說,塊之間的變量和函數是可以共享的。 這也是第二段代碼爲什麼可以訪問前一個塊裏的a
的原因。
step 1. 讀入第一個代碼塊。
step 2. 做語法分析,有錯則報語法錯誤(比如括號不匹配等),並跳轉到step5。
step 3. 對var變量和function定義做“預編譯處理”(永遠不會報錯的,因爲只解析正確的聲明)。
step 4. 執行代碼段,有錯則報錯(比如變量未定義)。
step 5. 如果還有下一個代碼段,則讀入下一個代碼段,重複step2。
step6. 結束。