ES6 新增了
let
指令,用來聲明變量,新增了
const
指令,用來聲明常量,它們的用法類似于
var
。
let a = 1;
var b = 2;
const PI = 3.14;
主要差別
塊級作用域
let
聲明的變量和
const
聲明的常量有塊級作用域,
var
聲明的變量則隻有函數作用域
{
let a = 1;
const PI = 3.14;
var b = 2;
}
console.log(a); //報錯
console.log(PI); //報錯
console.log(b); //2
function fun(){
let a = 1;
const PI = 3.14;
var b = 2;
}
console.log(a); //報錯
console.log(PI); //報錯
console.log(b); //報錯
不存在變量提升
var
聲明的變量存在變量提升,即變量可以在聲明之前使用,值為
undefined
。
let
聲明的變量和
const
聲明的常量不存在變量提升,
console.log(b); //undefined
var b = 2;
console.log(a); //報錯
let a = 1;
console.log(PI); //報錯
const PI = 3.14;
不能重複聲明
let
和
const
不允許在相同作用域内,重複聲明同一個變量,
var
則可以。
{
let a = 1;
let a = 2; //報錯
}
{
let a = 1;
var a = 2; //報錯
}
{
let a = 1;
const a = 2; //報錯
}
{
var a = 1;
const a = 2; //報錯
}
{
var a = 1;
var a = 2; //不報錯
}
暫時性死區
在代碼塊内,使用
let
指令聲明變量(或者
const
聲明常量)之前,該變量(常量)都是不可用的,這種情況稱為“暫時性死區”。
var a = 1;
{
console.log(a); //報錯
let a = 1;
}
var PI = 3;
{
console.log(PI); //報錯
const PI = 3.14;
}
其他差別
在全局作用域下用
var
聲明的常量會作為
window
對象的屬性儲存,
let
和
const
不會。
var a = 1;
let b = 2;
const PI = 3.14;
console.log(window.a); //1
console.log(window.b); //undefined
console.log(window.PI); //undefined
const
聲明的常量在聲明的時候必須指派,
let
和
var
可以隻聲明不指派,此時變量的值為
undefined
。
var a;
let b;
const PI; //報錯
console.log(a); //undefined
console.log(b); //undefined
const
聲明的常量在聲明後就不能被修改。
const PI = 3.14;
PI = 3.1415; //報錯
const
實際上保證的,并不是變量的值不得改動,而是變量指向的那個記憶體位址所儲存的資料不得改動。對于簡單類型的資料,值就儲存在變量指向的那個記憶體位址,是以等同于常量。但對于複合類型的資料,變量指向的記憶體位址,儲存的隻是一個指向實際資料的指針,
const
隻能保證這個指針是固定的(即總是指向另一個固定的位址),至于它指向的資料結構是不是可變的,就完全不能控制了。是以
const
如果聲明的是複合類型資料,則可以修改其屬性。
const PERSON = {
name : "XD"
};
PERSON.name = "JH";
console.log(PERSON.name); //"JH"
可以使用
Object.freeze(obj)
方法将對象當機。
const PERSON = Object.freeze({
name : "XD"
});
PERSON.name = "JH"; //正常模式時,該行不起作用;嚴格模式下會報錯。
除了将對象本身當機,對象的屬性如果也指向一個對象,那麼這個對象也應該當機。下面是一個将對象徹底當機的函數。
var constantize = function(obj){
Object.freeze(obj);
Object.keys(obj).forEach(function(key , i){
if(typeof obj[key] === 'object'){
constantize(obj[key]);
}
});
};