https://www.jianshu.com/p/3b5f0cb59344
https://jingyan.baidu.com/article/4f34706e18745be386b56d46.html
https://www.2cto.com/kf/201401/273825.html
http://www.javashuo.com/article/p-apunkzvq-eh.htmlhtml
JavaScript代碼的執行是由瀏覽器中的JavaScript解析器來執行的。JavaScript解析器執行JavaScript代碼的時候,分爲兩個過程:預解析過程和代碼執行過程。即先解析(例如先進行變量、函數的聲明提高),後運行。瀏覽器
JavaScript 運行分爲兩個階段: - 預解析 - 全局預解析(全部變量和函數聲明都會提早;同名的函數和變量函數的優先級高) - 函數內部預解析(全部的變量、函數和形參都會參與預解析) - 函數 - 形參 - 普通變量 - 執行 先預解析全局做用域,而後執行全局做用域中的代碼, 在執行全局代碼的過程當中遇到函數調用就會先進行函數預解析,而後再執行函數內代碼。
- 把變量的聲明提高到當前做用域的最前面,只會提高聲明,不會提高賦值。
- 把聲明式函數(JS有賦值式函數/函數表達式var f = function(){},這個不能被提高)的聲明提高到當前做用域的最前面,只會提高聲明,不會提高調用。
- 先提高var,在提高function
打印2次2。由於foo()提高到當前做用域的頂部。函數
function foo() { console.log('1'); }; foo(); function foo() { console.log('2'); }; foo();
JS解釋器逐個塊(一個<script>就是一個塊)解釋。先到第一個<script>,f1提高到全局做用域(打印哈哈)。到第二個<script>,最新的function f1的聲明提高到全局做用域,固然執行最新的一個聲明(打印嘎嘎)。code
<script> function f1() { console.log("哈哈"); } f1(); </script> <script> f1(); function f1() { console.log("嘎嘎"); } </script> <script> f1(); </script>
// 一、----------------------------------- var num = 10; fun(); function fun() { console.log(num); var num = 20; } //二、----------------------------------- var a = 18; f1(); function f1() { var b = 9; console.log(a); console.log(b); var a = '123'; } // 三、----------------------------------- f1(); console.log(c); console.log(b); console.log(a); function f1() { var a = b = c = 9; console.log(a); console.log(b); console.log(c); }
在ES5以前JS沒有塊級做用,有函數做用域。用函數做用域能夠避免多個<script>的全局變量污染。先能夠認爲JS通常沒有塊級做用域,有函數做用域。
塊級做用域: "{}內部聲明的變量只可以在{}內部訪問到,在{}外部沒法訪問到其內部聲明的變量"htm
當咱們在局部做用域中,訪問一個變量時,系統首先會在當前做用域中尋找變量var的聲明語句,如找到則直接使用。反之,則繼續向上一級做用域中尋找var的聲明語句,如找到則直接使用,反之,繼續向上一級做用域中去尋找…直到全局做用域blog
<script> var num = 10; function f1() { var num = 20; function f2() { var num = 30; function f3() { var num = 50; console.log(num); } f3(); } f2(); } f1(); </script>
在function裏,用var定義的變量是局部變量;不用var定義的變量爲隱式全局變量ip
function f1() { var a;//局部變量 a = 9; //隱式全局變量 b = 9; c = 9; console.log(a);//9 console.log(b);//9 console.log(c);//9 } f1(); console.log(c);// 9 console.log(b);// 9 console.log(a);//報錯