當前位置:
首頁 > 最新 > ES6之塊級作用域

ES6之塊級作用域

作用域

作用域指變數所作用的範圍,在 Javascript 中有兩種作用域:

全局作用域

函數作用域

變數提升

變數提升(Hoisting)被認為是, Javascript 中執行上下文 (特別是創建和執行階段)工作方式的一種認識。具體表現就是所有通過 var 聲明的變數會提升到當前作用域的最前面。

可以看到用 var 聲明了的並不會報錯。因為其實函數 bar 等同於

大多數類 C 語言語法的語言都擁有塊級作用域。在一個代碼塊(括在一對花括弧中的一組語句)中定義的所有變數在代碼塊的外部是不可見的。定義在代碼塊中的變數在代碼塊被執行結束後會變釋放掉。這是件好事。

糟糕的是,儘管 Javascript 的代碼貌似支持塊級作用域,但實際上 Javascript 並不支持(就是因為有變數提升)。這個混淆之處可能成為錯誤之源。

所以在 ES6 中規定了 let 和 const 來支持塊級作用域。但是,是不是真的提升就不存在了呢,可以看下面暫時性死區這部分。

let

let 可以理解為『更完美的 var』,使用方法很簡單;

使用方法基本和 var 相同,而且聲明的變數只在其塊和子塊中可用,這點也與 var 相同。 二者之間最主要的區別在於 var 聲明的變數的作用域是整個封閉函數。

let 聲明的變數的作用域只是外層塊,而不是整個外層函數。

我們可以利用這個特性來替代立即執行函數(IIFE)。

const

const 的用法跟 let 差不多,但是 const 一定要初始化, 不初始化是會報錯的。

const 是塊級作用域,const 跟 let 的語義相似,就是用來聲明常量的,一旦聲明了就不能更改。值得注意的是 const 聲明的變數記錄的是指針,不可更改的是指針,如果 const 所聲明的是對象,對象的內容還是可以修改的。

暫時性死區

使用 let 或 const 聲明的變數,在聲明沒有到達之前,訪問該變數都會導致報錯,就連一直以為安全的 typeof 也不再安全。

報的錯是 ReferenceError,如果使用 var 聲明的話,temp 輸出應該是 undefined,從 let 聲明的變數的塊的第一行,到聲明變數之間的這個區域被稱作暫時性死區(TDZ)。凡是在這個區域使用這些變數都會報錯。

看到上面兩個例子仔細思考有沒有覺得想到點什麼?

在函數里沒有用 let 聲明 temp 的時候,temp 是 undefined,講道理在 let 聲明前也應該是 temp,然而 foo 函數卻報了錯,證明了就算是在未到達 let 聲明的地方,但是在用 let 之前已經起到了作用。這是不是說明其實 let 也有提升,只是在 TDZ 使用的時候報錯了,而不是 undefined。

事實上,當 JS 引擎檢視下面的代碼塊有變數聲明時,對於 var 聲明的變數,會將聲明提升到函數或全局作用域的頂部,而對 let 或 const 的時候會將聲明放在暫時性死區內。任何在暫時性死區內訪問變數的企圖都會導致「運行時」錯誤(runtime error)。只有執行到變數的聲明語句時,該變數才會從暫時性死區內被移除並可以安全使用。

禁止重複聲明

在同一個塊內,let 和 const 不能聲明相同的標識符。禁止的情況包括:

let 或 const 和 let 或 const

var 和 let 或者 const

函數參數與 let 或 const

以上情況都是會報 SyntaxError。但是在嵌套的作用域內使用 let 聲明同一變數是被允許的。

同時因為是 let 和 const 是塊級作用域,聲明的變數在當前塊使用完之後就會被釋放,所以就算使用相同的標識符也不會覆蓋外部作用域的變數, 而 var 是會覆蓋外部作用域的變數的。

最佳實踐

在 ES6 的發展階段,被廣泛認可的變數聲明方式是:默認情況下應當使用 let 而不是 var 。對於多數 JS 開發者來說, let 的行為方式正是 var 本應有的方式,因此直接用 let

替代 var 更符合邏輯。在這種情況下,你應當對需要受到保護的變數使用 const。

在默認情況下使用 const ,而只在你知道變數值需要被更改的情況下才使用 let 。這在代碼中能確保基本層次的不可變性,有助於防止某些類型的錯誤。

思考題


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 前端桃園 的精彩文章:

TAG:前端桃園 |