1. 程式人生 > >javascript變數提升,ES6中var,let,const的區別

javascript變數提升,ES6中var,let,const的區別

在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主角登場: 我們通常用 letconst 來宣告,let 表示變數const 表示常量letconst 都是塊級作用域。怎麼理解這個塊級作用域?

  • 在一個函式內部
  • 在一個程式碼塊內部
說白了只要在{}花括號內的程式碼塊即可以認為 let 和 const 的作用域。

看以下程式碼:

function aa() {
    if(flag) {
       let test = 'hello man'
    } else {
        //test 在此處訪問不到
        console.log(test)
    }
  }

let 的作用域是在它所在當前程式碼塊,但不會被提升到當前函式的最頂部。

再來說說 constconst 宣告的變數必須提供一個值,而且會被認為是常量,意思就是它的值被設定完成後就不能再修改了。

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 簡潔的解決方案是不是更讓你心動!!!