"Code tailor",爲前端開發者提供技術相關資訊以及系列基礎文章,微信關注「小和山的菜鳥們」公衆號,及時獲取最新文章。
在開始學習以前,咱們想要告訴您的是,本文章是對阮一峯《ECMAScript6 入門》一書中 "let 和 const 命令" 章節的總結,若是您已掌握下面知識事項,則可跳過此環節直接進入題目練習javascript
若是您對某些部分有些遺忘,👇🏻 已經爲您準備好了!前端
let 和 const 的學習java
在 ES5 中,只有全局做用域和函數做用域,沒有塊級做用域,這帶來了不少不合理的場景,好比:內層變量可能覆蓋外層變量、用來計數的循環變量泄露爲全局變量。因此,let 和 const 實際上引入了「塊級做用域」的概念es6
var 命令會發生」變量提高「的的現象,即變量可在聲明以前使用,而通常邏輯是先聲明變量再去使用變量。故爲了糾正此現象,let 命令改變了語法行爲,即它所聲明的變量必定要在聲明後使用。
// var 的狀況 console.log(foo) // 輸出undefined var foo = 2 // let 的狀況 console.log(bar) // 報錯ReferenceError let bar = 2
塊級做用域可經過新增命令 let 和 const 聲明,所聲明的變量在指定塊的做用域外沒法被訪問。塊級做用域在以下狀況被建立:微信
function f1() { let n = 5 if (true) { let n = 10 } console.log(n) // 5 }
{ let a = 10 console.log(a) //10 } console.log(a) //undefined
console.log(bar) // 報錯ReferenceError let bar = 2
//報錯 let a = 10 let a = 20
const MAX = 1000000 const MIN //SyntaxError const MAX = 10000 //報錯
在代碼塊內,使用 let 命令聲明變量以前,該變量都是不可用的。這在語法上,稱爲「暫時性死區」(temporal dead zone,簡稱 TDZ)
if (true) { // TDZ開始 tmp = 'abc' // ReferenceError console.log(tmp) // ReferenceError let tmp // TDZ結束 console.log(tmp) // undefined tmp = 123 console.log(tmp) // 123 } //上面代碼中,在let命令聲明變量tmp以前,都屬於變量tmp的「死區」。
一: 下面的代碼輸出什麼?函數
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1) } for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1) }
0 1 2
and 0 1 2
0 1 2
and 3 3 3
3 3 3
and 0 1 2
Answer:C學習
因爲 JavaScript 中存在事件隊列,所以在執行循環以後會調用setTimeout
回調函數。由於第一個循環中的變量 i 是使用var
關鍵字聲明的,因此這個值是全局的。在循環過程當中,咱們使用一元運算符++
將 i 的值每次遞增 1。在調用setTimeout
回調函數時,在第一個示例中 i 等於 3。在第二個循環中,變量 i 是使用 let 關鍵字聲明的:使用let
(and const
)關鍵字聲明的變量是塊範圍的(塊是介於{}之間的任何東西)。在每次迭代中,都會有一個新值,每一個值的做用域都是獨立的。code
二: 下面代碼輸出什麼?隊列
function sayHi() { console.log(name) console.log(age) var name = 'Lydia' let age = 21 } sayHi()
Lydia
and undefined
Lydia
and ReferenceError
ReferenceError
and 21
undefined
and ReferenceError
Answer:D事件
在函數中,咱們首先用 var 關鍵字聲明 name 變量。這意味着變量將被提高(內存空間在建立階段設置),默認值爲 undefined,直到咱們實際到達定義變量的行。咱們尚未在試圖記錄 name 變量的行中定義變量,因此它仍然保存 undefined 的值。
帶有 let 關鍵字(和 const)的變量會被提高,但與 var 不一樣的是,不會被初始化。在咱們聲明(初始化)它們以前,它們是不可訪問的。這就是所謂的「暫時死區」。當咱們試圖在聲明變量以前訪問它們時,JavaScript 拋出一個 ReferenceError。
三: 下面代碼輸出什麼?
let name = 'Lydia' function getName() { console.log(name) let name = 'Sarah' } getName()
Lydia
Sarah
undefined
ReferenceError
Answer:D
每一個函數都有本身的執行上下文(或做用域)。getName 函數首先在它本身的上下文(做用域)中查看它是否包含咱們試圖訪問的變量名。在本例中,getName 函數包含它本身的 name 變量:咱們用 let 關鍵字和'Sarah'值聲明變量名。
帶有 let 關鍵字(和 const)的變量會被提高,但與 var 不一樣的是,不會被初始化。在咱們聲明(初始化)它們以前,它們是不可訪問的。這就是所謂的「暫時死區」。當咱們試圖在聲明變量以前訪問它們時,JavaScript 拋出一個 ReferenceError。
若是咱們沒有在 getName 函數中聲明 name 變量,javascript 引擎就會向下查看做用域鏈。外部做用域有一個名爲 name 的變量,其值爲 Lydia。若是那樣的話,它會記錄爲 Lydia。