一、作用域概念、預解析規則、表達式 1、作用域概念 什麼是作用域:簡單說就是作用的範圍,指的是函數在哪些範圍內可以用,而在其他部分就不可以使用,如果需要使用就需要重新定義。 作用域的作用是什麼:用來執行讀或者寫的操作。 2、預解析規則 script:自上而下進行解析, 函數:由里到外進行解析。 但是 ...
一、作用域概念、預解析規則、表達式
1、作用域概念
什麼是作用域:簡單說就是作用的範圍,指的是函數在哪些範圍內可以用,而在其他部分就不可以使用,如果需要使用就需要重新定義。
作用域的作用是什麼:用來執行讀或者寫的操作。
2、預解析規則
script:自上而下進行解析,
函數:由里到外進行解析。
但是瀏覽器在執行JS代碼的時候會分成兩部分操作:預解析以及逐行執行代碼
預解析:瀏覽器在開始工作的時候會先解讀JS代碼的關鍵字:比如:var function 參數等,並把解析到的內容存入一個類似倉庫的地方,這個過程一般稱為JS預解析。
並且,在這個階段所有的變數,在正式運行代碼之前,都會提前賦值為未定義。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <script> alert(a); var a = 1; </script> </head> </html>
代碼執行結果
函數在正式運行代碼之前則是整個函數塊。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <script> alert(a); function a () { alert(2); } </script> </head> </html>
代碼執行結果
在這個過程中如果函數和變數重名的話只會保留函數。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <script> alert(a); var a = 1; function a () { alert(2); } </script> </head> </html>
代碼執行結果:
逐行解讀代碼:在這個階段瀏覽器會一行一行的進行解讀,並找到關鍵字然後調用預解析階段儲存在“倉庫”的信息。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <script> alert(a); var a = 1; alert(a); function a () { alert(2); } alert(a); var a = 3; alert(a); function a () { alert(4); } alert(a); </script> </head> </html>
首先在這個階段已經完成了代碼的預解析,通過代碼的預解析我們知道預解析的結果為 a = function a () { alert(4)},
那麼上邊的代碼第一次彈出的一定是a = function a () { alert(4)}請看下圖
當執行到第二行時(也就是 var a = 1;)這個時候由於我們對a進行了賦值,所以第三行alert的展示結果應該是1;
當執行到第四行的時候(function a () { alert(2)};)由於它又變成了函數,但是由於函數不是表達式它不會改變值,所以執行完第五行之後會彈出1;
當代碼執行到第六行(var a = 3;)的時候,由於我們給變數進行了賦值,此時a=1變成了a=3;所以第七行彈出的結果為3;
當代碼執行到第八行的時候(function a(){ alert();}由於函數不改變值的原則,所以第九行彈出的結果依舊為3;
最後當代碼解讀完畢之後這個時候“倉庫”裡邊儲存的信息就是這樣的 a = 3;怎麼確認這個結果就是數字呢,我們可以使用typeof進行驗證
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <script> alert(a); var a = 1; alert(a); function a () { alert(2); } alert(a); var a = 3; alert(a); function a () { alert(4); } alert(a); alert(typeof a); </script> </head> </html>
執行結果為
3、表達式
在將上邊的問題的時候我們遇到一個現象:就是函數不會改變值,但是表達式卻可以。
首先先來總結一下表達式有哪些?
表達式:= + - * / % ++ -- ! 參數……
作用:表達式可以修改預解析的值!