let,const,var三者之間的區別
在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;
let,const,var三者之間的區別