深入理解ES6之let與const

爲什麼ES6不鼓勵用var聲明變量了

在函數作用域或全局作用域中通過關鍵字var聲明的變量,無論實際上是在哪裏聲明的,都會被當成是在當前作用域頂部聲明的變量。

  • 舉個栗子:
function getValue(condition){
	if(condition){
		var value = "blue";
		return value;
	}
	else{
		return null;
	}
}

這段代碼按正常的眼光來看待,只有當condition的值爲true的時候,變量value纔會被創建,但是實際上,無論condition的值是什麼,變量value都會被創建。在預編譯階段,JavaScript引擎會將上面的代碼修改成這樣。

function getValue(condition){
	var value;
	if(condition){
		value = "blue";
		return value;
	}
	else{
		return null;
	}
}

正如我在開頭所說的那樣,變量value 的聲明被提升到了函數的頂部,但是賦值操作卻依然在原處執行,這也就意味着,在else字句裏,value變量也是能被訪問到的,但是因爲沒有賦值,所以得到的結果是undefined。
這個機制被稱爲 變量提升(Hoisting)機制

塊級聲明

塊級聲明用於聲明在指定塊的作用域之外無法訪問的變量。塊級作用域存在於:

  • 函數內部
  • 塊中1

簡單來說就是用塊級聲明所聲明的變量只能在該代碼塊中發揮作用。

let聲明

let聲明是塊級聲明,let聲明在用法上和var是一樣的,用let代替var來聲明變量可以把變量的作用域限制在當前代碼塊中。let聲明是不存在變量提升機制的,因此用let聲明變量時一般把聲明語句放在代碼塊的頂部,以便整個代碼塊都可以訪問到該變量。
舉個栗子:

function getValue(condition){
	if(condition){
		let value = "blue";
		return value;
	}
	else{
		//變量value在這裏是不存在的
		return null;
	}
	//變量value在這裏是不存在的
}

let的禁止重聲明:如果作用域中已經存在某個標識符,此時再使用let來試圖聲明它就會報錯。
舉個栗子:

var a = 1;
let a = 2;

此時let不會給a賦值爲2,而是會拋出錯誤,因爲在一個作用域中不能用let重複定義已經存在的標識符。

var a = 1;
if(condition){
	let a = 2;
}

這樣聲明變量是不會報錯的,因爲它們不在同一個作用域中,所以不存在重聲明的問題。

const聲明

const聲明是塊級聲明,使用const聲明得到的不是變量而是常量,其值被初始化之後就不可以更改,這也意味着使用const聲明常量必須進行初始化操作,如果用const聲明常量時沒有賦值將會拋出語法錯誤。
舉個栗子:

const my_name = "炒米粉";
//語法錯誤,常量未初始化。
const my_age;
//語法錯誤,常量的值不能被改變
my_name = "炒河粉";

值得一提的是,const也是禁止重聲明的,這點與let一致,這裏就不贅述了。

用const聲明對象:用const來聲明對象的話是不允許修改綁定關係的,但是允許修改對象的屬性值。
舉個栗子:

const boy = {
	name:"炒米粉"
};
//修改對象屬性的值是沒有問題的
boy.name = "帥氣的炒米粉";
//拋出語法錯誤
boy = {
	name:"帥氣的炒米粉"
};

臨時死區(Temporal Dead Zone)

JavaScript引擎在掃描代碼發現聲明的時候,要麼將聲明提升到作用域頂部(var的變量提升機制),要麼將聲明放入TDZ中(遇到let或const)。
訪問TDZ中的變量將會拋出錯誤,當執行過變量聲明語句後,該變量纔會從TDZ中移出
舉個栗子:

//num的TDZ起點
console.log("DO SOMETHING");
console.log(typeof num);
//num的TDZ終點
let num = 1;

上面的代碼是會報錯的,因爲第二行代碼仍處於num的TDZ中,卻訪問了num。
上面的栗子用的是let,如果換成const結果也是一樣的。
相比上面的代碼,這一段反而不會報錯:

console.log(typeof num);//"undefined"
if(condition){
	let num = 1;
}

因爲第一行代碼是試圖訪問當前作用域中並不存在的變量,所以得到的是undefined,而不會報錯。


  1. 塊的定義:在字符 {} 之間的區域 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章