在ES6中新增了兩種定義變量的命令let和const,在這之前相信大家都對var定義變量很熟悉,那么在了解ES6方法前,
1.我們先來回顧一下var定義變量的方法。
下面來看這段代碼:
for (var i = 0; i < 10; i++) {
console.log(i);
}
alert(i)
在javascript中沒有塊級作用域,在for()里面定義變量i ,在循環外部依然可以進行正常訪問。var定義變量還有一個問題如下:
var i = 15;
var i = 5;
alert(i);//5
其中變量i重復定義沒有報錯,反而輸出值為5,說明被復寫了。用var定義變量還存在一個問題如下:
for (var i = 0; i < 3; i++) { setTimeout(function () { console.log(i) }, 1000); }
輸出結果為3,3,3,因為當循環結束時,i的值為三。所以在執行setTimeout函數時會打印三次3。(注釋,如果將var替換成let就不會出現這個問題)
2. 在介紹完var后,我們來學習下ES6中的兩種定義變量的命令,首先來學習let:
ES6 新增了let命令,用來聲明變量。它的用法類似於var,但是所聲明的變量,只在let命令所在的代碼塊內有效。請看下面代碼
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
for循環的計數器,就很合適使用let命令。
for (let i = 0; i < 10; i++) { // ... } console.log(i); // ReferenceError: i is not defined
上面代碼中,計數器i只在for循環體內有效,在循環體外引用就會報錯。說明:使用let,聲明的變量僅在塊級作用域內有效;
var命令會發生”變量提升“現象,即變量可以在聲明之前使用,值為undefined。這種現象多多少少是有些奇怪的,按照一般的邏輯,變量應該在聲明語句之后才可以使用。為了糾正這種現象,let命令改變了語法行為,它所聲明的變量一定要在聲明后使用,否則報錯。
// var 的情況 console.log(foo); // 輸出undefined var foo = 2; // let 的情況 console.log(bar); // 報錯ReferenceError let bar = 2;
上面代碼中,變量foo用var命令聲明,會發生變量提升,即腳本開始運行時,變量foo已經存在了,但是沒有值,所以會輸出undefined。變量bar用let命令聲明,不會發生變量提升。這表示在聲明它之前,變量bar是不存在的,這時如果用到它,就會拋出一個錯誤。說明:ES6 明確規定,如果區塊中存在let和const命令,這個區塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯。總之,在代碼塊內,使用let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)。
3.下面來講解const:
const聲明一個只讀的常量。一旦聲明,常量的值就不能改變。
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
上面代碼表明改變常量的值會報錯。const聲明的變量不得改變值,這意味着,const一旦聲明變量,就必須立即初始化,不能留到以后賦值。
const foo; // SyntaxError: Missing initializer in const declaration
上面代碼表示,對於const來說,只聲明不賦值,就會報錯。const的作用域與let命令相同:只在聲明所在的塊級作用域內有效。
if (true) { const MAX = 5; } MAX // Uncaught ReferenceError: MAX is not defined
const命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。
if (true) { console.log(MAX); // ReferenceError const MAX = 5; }
上面代碼在常量MAX聲明之前就調用,結果報錯。const聲明的常量,也與let一樣不可重復聲明。
var message = "Hello!"; let age = 25; // 以下兩行都會報錯 const message = "Goodbye!"; const age = 30;
