1. 程式人生 > 實用技巧 >Hoisting(變數提升)

Hoisting(變數提升)

var 和 let 的區別是什麼?

答案之一就有 let 不會變數提升

那麼,什麼是變數提升?

變數提升(Hoisting)被認為是, Javascript中執行上下文 (特別是建立和執行階段)工作方式的一種認識。 --MDN

基本概念

console.log(a);  // 輸出 undefined
var a = 1;

這裡使用var宣告一個變數a,我們卻能在宣告之前使用,這裡究竟發生了什麼?
原來,使用var宣告一個變數的時候,不管你在哪裡宣告,執行程式的時候都會先將這個宣告移動到作用域的最前面,而賦值操作則留在原處。
以上程式碼可以看做

var a;
console.log(a);  // 輸出 undefined
a = 1;

變數提升能否跨作用域

foo()
console.log(a)
function foo() {
      var a = a
      console.log('foo')
}

執行結果

a is not defined說明變數提升存在作用域
這裡發生了一個有趣的現象,我們在宣告函式foo前呼叫了它,可以看出已經正常執行
所以我們意外地得到一個結論,使用function宣告函式存在整體的提升
上面的程式碼等同於

function foo() {
      var a = a
      console.log('foo')
}
foo()
console.log(a)

變數提升能否跨script標籤

<script>
console.log(a);
</script>
<script>
var a = 1;
</script>

執行結果

結論 變數提升不能跨script

var和function都存在提升,那麼這個提升是否存在優先順序

console.log(a)
var a = 1
function a () {}
console.log(a)

執行結果

函式整體提升了,然後給a重新賦值為1,所以先輸出了函式

console.log(a)
function a () {}
var a = 1
console.log(a)

執行結果

沒有發生變化,我得到的結論是function

會整體提升,var只是宣告一個變數,如果變數已存在則不會再次宣告

var宣告函式變數不存在整體提升

使用var宣告只存在變數提升

console.log(a)
a()
var a = funciton () {}

執行結果

變數提升只會宣告一個值為undefined的變數