摘自阮一峰的es6教程 http://es6.ruanyifeng.com/#docs/let ...
文章內容摘自阮一峰的 ECMAScript 6 入門
ES6新增了let
命令,用來聲明變數。它的用法類似於var
,但是所聲明的變數,
- 只在
let
命令所在的代碼塊內有效,並且不存在變數提升(也叫預解釋)。
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
上面代碼在代碼塊之中,分別用let
和var
聲明瞭兩個變數。然後在代碼塊之外調用這兩個變數,結果let
聲明的變數報錯,var
聲明的變數返回了正確的值。這表明,let
聲明的變數只在它所在的代碼塊有效。
for
迴圈的計數器,就很合適使用let
命令。
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
上面代碼中,變數i
是let
聲明的,當前的i
只在本輪迴圈有效,所以每一次迴圈的i
其實都是一個新的變數,所以最後輸出的是6
。你可能會問,如果每一輪迴圈的變數i
都是重新聲明的,那它怎麼知道上一輪迴圈的值,從而計算出本輪迴圈的值?這是因為 JavaScript 引擎內部會記住上一輪迴圈的值,初始化本輪的變數i
時,就在上一輪迴圈的基礎上進行計另外,for
迴圈還有一個特別之處,就是迴圈語句部分是一個父作用域,而迴圈體內部是一個單獨的子作用域。
for (let i = 0; i < 3; i++) { let i = 'abc'; console.log(i); } // abc // abc // abc
上面代碼輸出了3次abc
,這表明函數內部的變數i
和外部的變數i
是分離的。
- 暫時性死區
只要塊級作用域記憶體在let
命令,它所聲明的變數就“綁定”(binding)這個區域,不再受外部的影響。
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }
View Code上面代碼中,存在全局變數
tmp
,但是塊級作用域內let
又聲明瞭一個局部變數tmp
,導致後者綁定這個塊級作用域,所以在let
聲明變數前,對tmp
賦值會報錯
ES6明確規定,如果區塊中存在let
和const
命令,這個區塊對這些命令聲明的變數,從一開始就形成了封閉作用域(暫時性死區)。凡是在聲明之前就使用這些變數,就會報錯。 - 暫時性死區的本質就是,只要一進入當前作用域,所要使用的變數就已經存在了,但是不可獲取,只有等到聲明變數的那一行代碼出現,才可以獲取和使用該變數。
function bar(x = y, y = 2) {//逗號的結合性是從左到右,所以先計算x=y表達式,所有報錯。 return [x, y]; } bar(); // 報錯
// 不報錯 var x = x; // 報錯 let x = x; // ReferenceError: x is not defined //在變數x的聲明語句還沒有執行完成前,就去取x的值,導致報錯”x 未定義“
-
不允許重覆聲明,
let
不允許在相同作用域內,重覆聲明同一個變數 -
ES6 聲明變數的六種方法
ES5 只有兩種聲明變數的方法:
var
命令和function
命令。ES6除了添加let
和const
命令,後面章節還會提到,另外兩種聲明變數的方法:import
命令和class
命令。所以,ES6 一共有6種聲明變數的方法。