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


let

  • let 聲明的變量只在 let 命令所在的代碼塊內有效。

小例1:數組

{
    let tmp = 5;
    console.log(tmp); // 5
}

console.log(tmp); // Uncaught ReferenceError: tmp is not defined
複製代碼

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

const

  • const 聲明一個常量(所謂常量就是物理指針不能夠更改的變量),聲明以後不容許改變。意味着,一但聲明必須初始化,不然會報錯。

小例:閉包

const I_MAX = 9999999;
console.log(I_MAX); // 9999999

const I_MIN; // Uncaught SyntaxError: Missing initializer in const declaration
console.log(I_MIN);
複製代碼
  • 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 definedui

  • let 聲明的變量不存在變量提高。

小例:spa

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 能夠聲明屢次變量。

小例:code

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同樣,都是塊級做用域,存在暫時性死區,不存在變量聲明提早,不容許重複定義,不會成爲全局對象的一個屬性。

相關文章
相關標籤/搜索