廢話不多說,直接開始。
我們看一段代碼(參考其他資料所得)
<script type="text/javascript">
function a(b){
console.log(b);
function b(){
console.log(b);
}
}
a(1);
</script>
運行結果是什么呢?請各位讀者先不要運行代碼,先思考一下猜猜結果。
——————————————————————————————————
不管你想的結果是幾個,不管你想的結果是不是1,唯一結果是:
function b(){
console.log(b);
}
是的,結果很以外(大神們請忽視我們這些小白),那為什么會出現這樣的結果呢?我們來根據結果逆推分析一下。
首先分析這段代碼:
1.創建函數a(b),傳遞的參數是b,
2. 輸出b,
3.a函數里面在輸出b后聲明一個函數b(),這個b()函數內容是輸出b,
4.調用函數a(1),傳遞1.
然后分析代碼的運行:
1、這個輸出是哪一行的呢?這段代碼運行時只調用了a()函數,b()函數只是聲明而沒有調用,所以這個輸出是函數a()里面的輸出,即第一個confole.log(b);
2、既然知道了輸出語句,就分析輸出內容,很明顯輸出的是b
3、根據輸出結果,這個b不是傳遞過來的參數b(調用時是1),而是a()函數里面聲明的子函數function b(),
4、傳遞的參數失效了
總上分析,我們好像明白了一點,在函數a()里面,子函數聲明的優先級(暫且這樣說)好像比參數的高啊
所以,雖然調用a()時傳遞了1給b,但是有立刻將b()函數給了變量b,執行后就輸出了function b()函數。
拓展:
通過以上的案例,並查詢其他資料,我總結一下函數中內部執行流程。
一段代碼寫完后到運行結束,分為兩個時期(我雖然學過編譯原理,但是跟沒學一樣,所以不會用詞):讀、運行。
1、讀一段代碼時,只管變量和函數的聲明,不管賦值,比如 var a=3;只知道有個變量叫a,值不管。
2、運行代碼時,比如調用函數a(1),傳遞參數1給形參b,之后並不執行cosole.log()函數,而是繼續找子函數聲明,於是找到了函數function b(),這個函數賦值給變量b
3、讀完了,到了運行代碼,運行console.log(b),自然輸出了function b()。
可能我的知識不足,上面涉及到的我只能這樣說了,以后有機會了好好研究研究。
歡迎大家批評指正哈。