javascript 變數提升(Hoisting)
簡介
“變數提升”意味著變數和函式的宣告會在物理層面移動到程式碼的最前面,但這麼說並不準確。
實際上變數和函式宣告在程式碼裡的位置是不會動的,而是在編譯階段被放入記憶體中。
宣告變數的方法
var、let、const
不用以上關鍵字直接賦值的變數會掛載與windows環境下;
let a=9 const a=1 var a=6 c=5
宣告函式的方法
javascript中宣告函式的方法有兩種:函式宣告式和函式表示式。
//函式宣告 function say(){ console.log('hello') } //函式表示式 var say=function (){ console.log('hello') }
提升的好處
JavaScript 在執行任何程式碼段之前,將函式宣告放入記憶體中的優點之一是,這允許你可以在在宣告該函式之前使用一個函式。
/*** 正確的方式:先宣告函式,再呼叫函式 (最佳實踐)*/ function catName(name) { console.log("我的貓名叫 " + name); } catName("Tigger"); /*以上程式碼的執行結果是: "我的貓名叫 Tigger"*/ /*** 不推薦的方式:先呼叫函式,再宣告函式 */ catName("Chloe"); function catName(name) { console.log("我的貓名叫 " + name); } /*程式碼執行的結果是: "我的貓名叫 Chloe"*/
提升規則
- var 宣告的變數,提升時只宣告,不賦值,預設為undefined;不用關鍵字直接賦值的變數不存在提升(demo1)
- 函式提升會連帶函式體一起提升,不執行;(deom2)
- 預解析的順序是從上到下;(demo4)
- 函式的優先順序高於變數,函式宣告提前到當前作用域最頂端;(deom3)
- 變數重名,提升時不會重複定義;在執行階段後面賦值的會覆蓋上面的賦值;(demo4)
- 函式重名,提升時後面的會覆蓋前面;(demo5)
- 函式和變數重名,提升函式,不會重複定義,變數不會覆蓋函式;在執行階段後面賦值的會覆蓋上面的賦值;(demo8)
- 用函式表示式宣告函式,會按照宣告變數規則進行提升;(deom6)
- 函式執行時,函式內部的變數宣告和函式宣告也按照以上規則進行提升;(deom7)
- let、const不存在提升;(demo9、demo10)
/**demo1**/ console.log('a=',a) //a=undefined console.log('b=',b) // Uncaught ReferenceError: b is not defined var a=1 b=6 /**deom2**/ console.log('a=',a)// a=functiona() {console.log("func a()")} functiona() { console.log("func a()") } /**deom3**/ console.log('a=',a) // a=functiona() {console.log("fun a")} var a=3 var a=4 function a(){ console.log("fun a") } var a=5 var a=6 console.log("a=",a) // a=6 /**deom4**/ console.log('a=',a)// a=undefined var a =2 console.log('a=',a) // var a =3 var a =4 console.log('a=',a) // a=4 console.log('b=',b) //b= undefined var b='b1' /**deom5**/ console.log('a=',a) // a=functiona() {console.log("a2")} function a(){ console.log("a1") } function a(){ console.log("a2") } console.log('a=',a) // a=functiona() {console.log("a2")} /**deom6**/ console.log('a=',a) // a=undefined var a=function(){console.log('a1')} var a=3 var a=4 var a=5 console.log(a) var a=function(){console.log('a2')} console.log('a=',a) // a= ƒ (){console.log('a2')} /**deom7**/ console.log('b=',b) var a=3 function b(i){ console.log('a=',a) var a=4 function a(){ console.log('fun a') } console.log('a=',a) } b() /**demo8**/ console.log('a=',a) //a= function a(){ console.log('fun a')} var a=2 function a(){ console.log('fun a') } console.log('a=',a) // a=2 var a=3 var a=4 var a=5 console.log('a=',a) // a=5 /**demo9**/ console.log('a=',a) //Uncaught ReferenceError: a is not defined let a=4 /****/ <!--demo10--> console.log('b=',b) // Uncaught ReferenceError: b is not defined const b=5