系列目錄
ES6+ 現在就用系列(一):為什么使用ES6+
ES6+ 現在就用系列(二):let 命令
ES6+ 現在就用系列(三):const 命令
ES6+ 現在就用系列(四):箭頭函數 =>
ES6+ 現在就用系列(五):模板字面量 (Template Literals)
ES6+ 現在就用系列(六):解構賦值 (Destructuring )
ES6+ 現在就用系列(七):Promise
ES6+ 現在就用系列(八):類 (Class),繼承,對象的擴展
ES6+ 現在就用系列(九):模塊
ES6+ 現在就用系列(十):Async 異步編程
ES6+ 現在就用系列(十一):ES7 Async in Browser Today
ES6新增了let命令,用來聲明變量。它的用法類似於var,但是所聲明的變量,只在let命令所在的代碼塊內有效。也就是有了塊級作用域。
為什么需要塊級作用域?
避免 var 變量提升帶來的副作用
示例:
var saleCount = 20;
function f(){
console.log(saleCount);
if(saleCount<100)
{
// according some rule, change it to 100
var saleCount=60;
console.log(saleCount);
}
}
f()
輸出: // undefined
因為 "var saleCount=60;" 作用域是整個函數,而JavaScript里var定義的變量存在變量提升,也就是console.log(saleCount), 這個saleCount是 "var saleCount=60;" 這一句定義的,當調用的時候,saleCount的值是undefined. 實際上等於下面代碼。
var saleCount = 20;
function f(){
var saleCount;
console.log(saleCount);
if(saleCount<100)
{
// according some rule, change it to 100
saleCount=60;
console.log(saleCount);
}
}
f() // undefined
避免循環變量變為全局變量
示例:
for (var i = 0; i < 10; i++){
// do something
}
console.log(i);
輸出: 10
很明顯,我們不希望i,這個變量變為全局變量。
let 示例代碼
'use strict'
{
var b=1;
let a=2;
}
console.log(a);
console.log(b);
# 輸出: ReferenceError: a is not defined
上一節我們給出了如下的示例:
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[1]();
a[2]();
a[3]();
輸出: 10,10,10
我們看到,輸出的結果不是我們想要的,因為i是用var定義的,那么他在全局范圍內都是生效的,也就是我們循環結束以后,i的值就是10,那么不管調用數組的那個元素,console.log(i) 輸出的都是10, 那么let因為有了塊級作用域,就可以避免這個問題。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[1]();
a[2]();
a[3]();
輸出 1, 2,3
另外,函數本身的作用域也在定義他的塊的作用域內。
function hello(){console.log("Hello, Jack")};
{
function hello(){console.log("Hello, Tom")};
}
hello();
上面的代碼在ES6里面輸出了"Hello, Jack", 而在ES5里輸出了"Hello, Tom".
注意事項
不能先使用,后定義
console.log(x);
console.log(y);
var x = 1;
let y = 2;
# 輸出
undefined
ReferenceError: y is not defined
上面的代碼由於x是var定義的,一開始x的變量是存在的,只是值是undefined, 但是由於y 是let定義的,就不存在變量提升。
暫時性死區
如果一個變量是使用let定義的,那么這個變量就屬於聲明時所在的代碼塊,也就是變量不再受外部影響,下面的a 由於在塊里定義了,所以 會報錯,因為在那個塊里是先使用后定義,如果去掉“let a”, 那么a就是外部的變量,這個時候就不會出錯。
var a = "hello";
{
a = 'world';
let a;
}
// ReferenceError
不能重復申明
也就是不能重復申明同一個變量,即使一個是let申明,一個是用var申明也不行。 下面的代碼都會報錯。
function () {
let a = 10;
var a = 1;
}
function () {
let b = 10;
let b = 1;
}
總結
由於let 避免了很多問題,所以建議在ES6的代碼里總是使用let 來替代var.