1.let命令
所宣告的變數命令所在**塊有效:
a;// referenceerror: a is not defined.
b;//1
for迴圈的計數器,就很適合let命令
for (let i = 0; i < arr.length; i++) {}
console.log(i);
//referenceerror: i is not
defined
使用var,最後輸出10
var a = ;
for (var i = 0; i < 10; i++) ;
}a[6](); // 10
變數i是var宣告的,在全域性範圍內都有效。所以每一次迴圈,新的i值都會覆蓋舊值,導致最後輸出的是最後一輪的i的值。
如果使用let,宣告的變數僅在塊級作用域內有效,最後輸出6
var a = ;
for (let i = 0; i < 10; i++) ;
}a[6](); // 6
i是let宣告的,當前i只在本輪迴圈有效,所以每一次迴圈的i其實都是乙個新的變數,所以最後輸出的是6。
不存在變數提公升:
let不像var那樣會發生變數提公升,所以變數一定要在宣告後使用。
console.
log(foo); // 輸出undefined
console.
log(bar); // 報錯referenceerror
var foo =
2;let bar =
2;
變數foo用var命令宣告,會發生變數提公升,即指令碼開始執行時,已經存在了,但是沒有值,所以輸出undefined。變數bar用let命令宣告,不會發生變數提公升,表示在宣告它之前,變數bar是不存在的,這是如果用到它,就會丟擲乙個錯誤。
暫時性死區
只要塊級作用域內存在let命令,它所宣告的變數就「繫結」這個區域,不在受外部的影響。
var tmp = 123;
if (true)
存在全域性變數tmp,但是塊級作用域內let又宣告了乙個區域性變數tmp,導致後者繫結這個塊級作用域,所以let宣告變數前,對tmp賦值會報錯。
es6明確規定,如果區塊中存在let和const命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。凡是在宣告之前就使用這些變數,就會報錯。
總之在**塊內,使用let命令宣告變數之前,該變數是不可用的,稱為「暫時性死區」(temporal dead zone,簡稱tdz)。
if (true)
暫時性死區也意味著typeof不再是乙個安全的操作
typeof x; // referenceerror
let x;
如果乙個變數根本沒有被宣告,使用typeof反而不會報錯
typeof undeclared_variable // "undefined"
有些死區比較隱蔽,不太容易被發現:
function
bar(x = y, y = 2)
bar(); // 報錯
因為引數x預設值等於另乙個引數y,而此時y還沒有宣告,屬於死區。如果y的預設值是x,就不會報錯,因為此時x已經宣告了。
function
bar(x = 2, y = x)
bar(); // [2, 2]
es6規定暫時性死區和不存在變數提公升,主要是為了減少執行時錯誤,防止在變數宣告前就使用這個變數,從而導致意料之外的行為。
不允許重複宣告
let不允許在相同作用域內,重複宣告同乙個變數
// 報錯
function
() // 報錯
function
()
因此,不能再函式內部重新宣告引數
function
func
(arg)
function
func
(arg)
}
塊級作用域
只有全域性作用域和函式作用域,沒有塊級作用域,這帶來很多不合理的場景。
第一種場景,內層變數可能會覆蓋外層變數
var tmp = new
date();
function
f()
}f(); // undefined
函式f執行後,輸出undefined,原因在於變數提公升,導致內層的temp變數覆蓋了外層的tmp變數。
第二種場景,用來計數的迴圈變數洩露為全域性變數
var s = 'hello';
for (var i = 0; i < s.length; i++)
console.log(i); // 5
變數i用來控制迴圈,但是迴圈結束後,它沒有顯示,洩露成了全域性變數。
es6塊級作用域
function
f1()
console.log(n); // 5
}
上面的兩個**塊中,都宣告了變數n,執行後輸出5.外層**塊不受內層外碼塊的影響
因此可以在內層作用域和外層作用域定義同名的變數。
}}}};
es6引入了塊級作用域,明確允許在塊級作用域之中宣告函式。
2 const命令
const宣告乙個唯讀的常量。一旦宣告,常量的值就不能改變。const宣告的值不能改變,這意味著,const一旦宣告變數,就必須立即初始化,不能留到以後賦值。
const的作用域與let命令相同:只在宣告所在的塊級作用域內有效。
const命令宣告的常量也是不提公升,同樣存在暫時性死區,只能在宣告的位置後面使用。
if (true)
const宣告的常量,也與let一樣不可重複宣告。
const命令只是保證變數名指向的位址不變,並不保證該位址的資料不變,所以將乙個物件宣告為常量必須非常小心。
const foo = {};
foo.prop = 123;
foo.prop
// 123
foo = {}; // typeerror: "foo" is read-only
參考學習的**: es6學習筆記 let和const
console.log b uncaught referenceerror a is not defined 在for迴圈中,迴圈語句部分是乙個作用域,內部又是乙個作用域 for let a 1 a 3 a 在let宣告變數完成前,對變數賦值會出錯es中模仿塊級作用域 function functi...
ES6學習 let和const命令
說明 本文參考阮一峰的ecmascript 6 入門 console.log a 塊外使用會報錯 referenceerror a is not defined for迴圈內使用let和var產生的不同效果 下面 使用的是var,結果為10 var a for var i 0 i 10 i a 9 ...
ES6學習 let和const命令
es5只有兩種宣告變數的方法 var命令和function命令。es6新增了let命令和const命令宣告變數。let命令用來宣告變數,宣告的變數只能在let命令所在的 塊中有效。類似於var命令,var命令宣告的變數在全域性範圍內有效。const命令宣告乙個唯讀的常量,宣告時必須賦值,否則會報錯。...