JavaScript-JavaScript預解析

變量提升、函數提升

變量使用時會將變量聲明提升到作用域的上面。函數調用時會將函數聲明提升到作用域的上面。
 
提升:提升的只是定義,賦值不會被提升。
 
a = 100;
console.log(a);
var a;
test();
function test() {
    a = 101;
    console.log(a);
}
運行結果:

100
101

c、java等使用變量之前需要聲明變量/定義、初始化變量。JS中使用變量前無需聲明/定義,因此產生“變量提升/函數提升”的概念。

var a = 10;
(function() {
    var a = b = 100; // 等價於 (沒有var) b = 100, var a = b;
})();
console.log(a);
console.log(b);

1. 從函數內部找b,尋找失敗,轉向函數外部尋找b。
2. 函數外部找b,找不到就在全局創建b。 var b = 100;

運行結果:

10
100

實例:(知識點:變量提升、this概念)

a = 100;
console.log(a);
var a;
test();
function test() {
    a = 101;
    console.log(a);
    console.log(this.a);
}

運行結果:

100
101
undefined

this == window, node環境無window,因此this.a爲undefined。

小知識:

變量聲明和變量定義的區別?

  • 變量聲明分爲2種

    • 需要建立存儲空間。例如:int a; 聲明時爲a建立了存儲空間。

    • 無需創建存儲空間。例如: extern int a; a在其他地方定義。

通常將建立空間的稱爲“定義”,不建立空間的稱爲“聲明”。(可認爲定義是聲明的一個特例)

JS預解析

JS解析器執行JS代碼時分爲兩個過程:預解析過程和執行代碼過程。

預解析過程

JS解析器在執行第一步預解析的時候,會從代碼的開始搜索直到結尾,只去查找var、function等內容。一般把第一步稱之爲“JavaScript的預解析”。
 
第一步:將變量聲明提升至作用域最前面,初始化爲undefined。只提升聲明,不提升賦值。
第二步:將函數聲明提升至作用域最前面,初始化爲函數塊(正式運行前,函數都是整個函數塊)。只提升聲明,不提升調用。
注:
  • 只找var/function聲明的。
  • 先提升var,再提升function。
  • 遇到變量和函數重名了,只留下函數。
  • 遇到函數重名了,根據代碼的上下文順序,留下最後一個,變量也是一樣。
console.log(a);
var a=1;
console.log(a);
function a(){console.log(2);}
console.log(a);
var a=3;
console.log(a);
function a(){console.log(4);}
console.log(a);

1.找到第一個var存值爲undefined(注意不會爲其賦值爲1,而是undefined)

2.function a(){console.log(2);}代替前面var

3.var =3不會替代function

4.function a(){console.log(4);}替代function a(){console.log(2);}

5.預解析結果:把a=function a(){console.log(4);}存在預解析的倉庫裏面

  • 函數中的變量只會提前到函數的作用域中的最前面,不會出去。
  • 預解析會分段(多對的script標籤中函數重名,預解析的時候不會衝突)。
<script>
    function f1() {
        console.log("哈哈");
    }
</script>

<script>
    f1();
    function f1() {
        console.log("嘎嘎");
    }    
</script>
  • 作用域鏈

作用域鏈 : 執行表達式時,先在自己預解析中找,如果沒有找到,會向它的父級作用域找,如果找不到,報錯。

f1();
console.log(a); // ReferenceError: a is not defined
function f1() {
  var a=9;
  console.log(a);
}

參考鏈接:

https://blog.csdn.net/weixin_42787326/article/details/81328757 (JavaScript 解析器、預解析、變量提升、函數提升)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章