var
從 ECMAScript 一開始就存在,也是代表 Keyword,看到 var
就可以判斷是 ECMAScript 了。但 var
在 ECMAScript 2015 之後有了一些改變,重要性也不若以往,TC39 甚至建議完全不要使用 var
,改用 let
與 const
。
Verson
ECMAScript 5
ECMAScript 2015
Var
宣告變數於 function 內
或 function 外
(global)。
- Scope:為 execution context,分 function 內與 global,而非以
{}
定 scope - Auto Global:若沒
var
一個變數,會自動升級
成 global 變數 (ES5 ok、但 ES6 廢除) - Undefined:有
var
但未指定值,就是undefined
- Hoisting:無論你寫在 function 內第幾行,都會在 code 執行
前
的 creation phase 先宣告變數 - Redeclaration:若重新
var
一個變數,原來的值仍會存在
Scope
function x() {
var z = 2
}
x()
console.log(z) // ReferenceError
ES5 與 ES6 都無法執行。
z
的 execution context 為 function 內
,所以 function 外部抓不到 z
,會在 run-time 跳出 ReferenceError
。
z = 2
function x() {
console.log(z)
}
x() // ReferenceError
ES5 可執行,ES6 會噴 ReferenceError
。
在 ES5 允許 global variable 不使用 var
宣告變數,但 ES6 會啟動 strict mode
,儘管是 global variable,也一定要使用 var
。
Auto Global
function x() {
y = 1
}
x()
console.log(y) // ReferenceError
ES5 可執行,ES6 會噴 ReferenceError
。
y
在 ES5 會自動升級為 global 變數,還是會印出 1
,但 ES6 會啟動 strict mode
,y
無法升級成 global 變數,會在 runtime 跳出 ReferenceError
。
Undefined
console.log(x)
console.log('still going...') // RefferenceError
ES5 與 ES6 都無法執行。
Runtime ReferenceError
,因為 x
沒有 var
宣告。
var x
console.log(x) // undefined
console.log('still going...') // still going...
ES5 與 ES6 都可執行。
x
只宣告但沒有給值,因此為 undefined
。
ECMAScript 對於變數,沒有
預設值
,也不是null
,而是特有undefined
Hoisting
console.log(x) // undefined
var x = 2
x
在 console.log()
執行完才宣告並定義成 2
。
實際執行結果為 undefined
而非 ReferenceError
。
因為 engine 在執行前的 creation phase 會先建立 x
,並填入 undefined
,此稱為 Hoisting,因此先印出 undefined
。
var x = y, y = 'A'
console.log(x + y) // undefinedA
因為 var y
會先被 hoisting,所以 x = y
時,y
還是 undefined
,因此 x
也是 undefined
。
Redeclaration
var x = 2;
console.log(x)
var x;
console.log(x)
// 2
// 2
ES5 與 ES6 都可執行。
因此 var x
被 hoisting,所以結果都是 2
。
var x = 2
console.log(x)
var x = 3
console.log(x)
// 2
// 3
ES5 與 ES6 都可執行。
由於 hoisting 機制,ES5 允許 re-declare。
ES6 在 Babel 可編譯也可執行,但實務上不建議使用 redeclaration
Conclusion
- 在 ES6 無論 function 內的變數 或 global 變數,一律要使用
var
,否則會噴ReferenceError
- ECMAScript 有獨特的
undefined
,只要變數沒有給定值都是undefined
- 雖然 hoisting 允許 re-declare,但實務上不建議使用