javascript變數提升,ES6中var,let,const的區別
阿新 • • 發佈:2018-12-15
在ES6之前,我們都是用var
關鍵字宣告變數。無論宣告在何處,都會被視為宣告在函式的最頂部(不在函式內即在全域性作用域的最頂部)。這就是函式變數提升例如:
function aa() {
if(flag) {
var test = 'hello man'
} else {
console.log(test)
}
}
以上的程式碼實際上是:
function aa() { var test // 變數提升,函式最頂部 if(flag) { test = 'hello man' } else { //此處訪問 test 值為 undefined console.log(test) } //此處訪問 test 值為 undefined }
所以不用關心flag是否為 true
or false
。實際上,無論如何 test 都會被建立宣告。
接下來ES6主角登場:
我們通常用 let
和 const
來宣告,let
表示變數、const
表示常量。let
和 const
都是塊級作用域。怎麼理解這個塊級作用域?
- 在一個函式內部
- 在一個程式碼塊內部
說白了只要在{}花括號內的程式碼塊即可以認為 let 和 const 的作用域。
看以下程式碼:
function aa() { if(flag) { let test = 'hello man' } else { //test 在此處訪問不到 console.log(test) } }
let
的作用域是在它所在當前程式碼塊,但不會被提升到當前函式的最頂部。
再來說說 const
const
宣告的變數必須提供一個值,而且會被認為是常量,意思就是它的值被設定完成後就不能再修改了。
const name = 'lux'
name = 'joe' // 再次賦值此時會報錯
還有,如果 const
的是一個物件,物件所包含的值是可以被修改的。抽象一點兒說,就是物件所指向的地址不能改變,而變數成員是可以修改的。
const student = { name: 'cc' } // 沒毛病 student.name = 'yy' // 如果這樣子就會報錯了 student = { name: 'yy' }
說說TDZ(暫時性死區),想必你早有耳聞。
{
console.log(value) // 報錯
let value = 'lala'
}
我們都知道,JS引擎掃描程式碼時,如果發現變數宣告,用 var
宣告變數時會將宣告提升到函式或全域性作用域的頂部。但是 let
或者 const
,會將宣告關進一個小黑屋也是TDZ(暫時性死區),只有執行到變數宣告這句語句時,變數才會從小黑屋被放出來,才能安全使用這個變數。
哦了,說一道面試題。
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function() { console.log(i) })
}
funcs.forEach(function(func) {
func()
})
這樣的面試題是大家很常見,很多同學一看就知道輸出十次10 但是如果我們想依次輸出0到9呢? 有兩種解決方法,直接看一下程式碼:
// ES5知識,我們可以利用“立即呼叫函式”解決這個問題
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(
(function(value) {
return function() {
console.log(value)
}
})(i)
)
}
funcs.forEach(function(func) {
func()
})
// 再來看看es6怎麼處理的
const funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
funcs.forEach(func => func())
達到相同的效果,ES6 簡潔的解決方案是不是更讓你心動!!!