ES6 --- 新的變量聲明方式 let 與 const 解析

ES6 --- 新的變量聲明方式 let 與 const 解析

let

  • let 聲明的變量只在 let 命令所在的代碼塊內有效。
{
let tmp = 5;
console.log(tmp); // 5
}
console.log(tmp); // Uncaught ReferenceError: tmp is not defined

let 聲明的變量只在 let 命令所在的代碼塊內有效, 在代碼塊之外無效

const

  • const 聲明一個常量(所謂常量就是物理指針不可以更改的變量),聲明之後不允許改變。意味著,一但聲明必須初始化,否則會報錯。
const MAX = 9999999;
console.log(MAX); // 9999999
const MIN;
console.log(MIN); // Uncaught SyntaxError: Missing initializer in const declaration
  • const 除了不能改變物理指針的特性,其他特性和 let 一樣。

let const var 的區別

  • let 是在代碼塊內有效,var 是在全局範圍內有效。
{
var temA = 'A';
let temB = 'B'
}
console.log(temA); // A
console.log(temB); // Uncaught ReferenceError: temB is not defined

temA和temB都聲明在代碼塊裡面,temA是由var聲明,在外部可以直接訪問,temB是由let聲明,在外部不可直接訪問,提示錯誤:temB is not defined

  • let 聲明的變量不存在變量提升。
temA = 'A';
temB = 'B'; // Uncaught ReferenceError: temB is not defined
console.log(temA); // A
console.log(temB);

var temA;
let temB;

var 聲明的變量存在變量提升,所以temA在賦值語句下面聲明,沒有問題;let 聲明的變量不存在變量提升,所以temB在賦值語句下面聲明,提示錯誤:temB is not defined

  • let 只能聲明一次變量 var 可以聲明多次變量。
var temA = 'A';
let temB = 'B';
console.log(temA); // A
console.log(temB); // B
var temA = 'C';
let temB = 'D'; // Uncaught SyntaxError: Identifier 'temB' has already been declared
console.log(temA); // C
console.log(temB);
  • let存在暫時性死區
var tem = 3;
if (true) {
tem = 5; // Uncaught ReferenceError: tem is not defined
let tem;
}

ES6規定如果塊內存在let命令,那麼這個塊就會成為一個封閉的作用域,並要求let變量先聲明才能使用,如果在聲明之前就開始使用,它並不會引用外部的變量。

  • let 不會成為全局對象的一個屬性
var temA = 'A';
console.log(window.temA); // A
let temB = 'B';
console.log(window.temB); // undefined

var全局聲明後會作為全局對象window的一個屬性,而let不會,所以提示undefined

  • const和var的區別,除了const是聲明一個不可更改的常量外,和var的區別和let一致,也就是說上面幾點let和var的區別,同樣也是const和var的區別。

進階用法

  • 在for循環中使用let定義變量,只在for循環內可以使用。

實現將for循環中的i變量,存入arr數組中,for循環結束後,依次輸出。

// ES5的實現
var arr = [];
for(var i = 0; i < 3; i++){
arr.push(function (){
console.log(i);
})
}
arr[0]() // 3
arr[1]() // 3
arr[2]() // 3

為什麼每次輸入都是3,因為for循環每次做的事只是向數組中存入一個函數,但是函數並沒有立刻執行。i是通過var來聲明的。當for循環完,此時i的值是3。當你去執行函數的時候,自然輸出3

// ES5的閉包實現
var arr = [];
for(var i = 0; i < 3; i++){
arr.push((function (arg){
return function (){
console.log(arg);
}
})(i))
}
arr[0]() // 0
arr[1]() // 1
arr[2]() // 2

利用ES5的閉包也可以實現,但是代碼比較複雜,如果用ES6就比較簡單了,看下面代碼

// ES6的實現
let arr = [];
for(let i = 0; i < 5; i++){
arr.push(function (){
console.log(i);
})
}
arr[0]() // 0
arr[1]() // 1
arr[2]() // 2

為什麼這樣就能彈出 0,1,2? 其實需要注意個問題,就是這個let i=0;聲明的位置,是在for的()內,那麼你可以理解成,在for的內部就定義了一個i而且是使用let定義的。所以每次循環就相當於在當前循環的i值的前提下向數組push的。

總結:var let const 都是聲明變量的關鍵字,var的作用域是函數作用域,在一個函數內利用var聲明一個變量,則這個變量只在這個函數內有效。如果在函數外部聲明一個變量,則這個變量全局有效,var存在變量提升。const一般用來聲明常量,且聲明的常量是不允許改變的,只讀屬性,因此就要在聲明的同時賦值。const與let一樣,都是塊級作用域,存在暫時性死區,不存在變量聲明提前,不允許重複定義,不會成為全局對象的一個屬性。

(內容收集於網上,如有侵權請聯繫豬豬俠)


分享到:


相關文章: