let和const是es6新出的兩種變量聲明的方式,接下來我來分別針對這兩個,聊一聊。
let
let它的出現,我認為主要是解決了塊級作用域的需求。因為js以前本身是沒有什么塊級作用域的概念的(頂多就算上一個函數作用域),因此這也導致了很多變量污染的問題,很多時候由於你沒有處理好作用域的影響,導致了奇怪的問題。因此我們一般都采取函數作用域的方式來防止變量的污染。不過既然有了let的出現,我們就可以很方便的解決這個問題.
塊級作用域
for (var i = 0; i < 5; i++) {
console.log(i)
}
console.log(i) // 5
for (let j = 0; j < 5; j++) {
console.log(j)
}
console.log(j) // error: j is not defined
如上所示,如果我們在循環內部使用var聲明一個變量的話,當循環結束后,該變量並沒有被回收,而當我們使用let的時候,當離開這個塊的時候,該變量就會回收。
暫時性死區
var i = 5;
(function hh() {
console.log(i) // undefined
var i = 10
})()
let j = 55;
(function hhh() {
console.log(j) // ReferenceError: j is not defined
let j = 77
})()
看以上代碼,由於var它具有變量提升的功能,所以該聲明語句會移到最上面執行,也就是等價於以下代碼:
var i = 5;
(function hh() {
var i
console.log(i) // undefined
i = 10
})()
let j = 55;
(function hhh() {
console.log(j) // ReferenceError: j is not defined
let j = 77
})()
但是,如果將var換成let的話卻會報錯,如果說,let是沒有變量提升的話,那么應該是直接輸出55,而不應該報錯啊。
其實,這個特性叫做臨時性死區,也可以把它當成變量提升的一種特殊情況.也就是說,當你在一個塊里面,利用let聲明一個變量的時候,在塊的開始部分到該變量的聲明語句之間,我們稱之為臨時性死區,你不可以在這個區域內使用該變量,直到遇到其let語句為止。比如:
var i = 5; // j的臨時性死區
(function hh() {
var i
console.log(i) // undefined
i = 10
})() // j的臨時性死區
// j的臨時性死區
let j = 55; // 接下來可以愉快的使用let了
console.log(j)
console.log(j+10)
(function hhh() {
console.log(j) // 新的j的臨時性死區
let j = 77 //又有一個聲明語句,從這個函數的開始部分到這里,都是新的j的臨時性死區
})()
之所以說它是變量提升的一種特殊情況,是因為無論你在塊的哪一個地方利用let聲明了一個變量,都會產生一個從塊的開始部分到該變量聲明語句的臨時性死區.
比較安全可靠:對var或者是直接聲明全局變量來說,變量都可以未聲明或者在聲明語句之前就使用,而使用了let之后,該變量必須在其聲明語句后,才能使用,否則就會報錯。這就在一定程度上避免了變量濫用的情況。
const
const,顧名思義,就是聲明一個常量,但是,真的是這樣嗎?
對基本類型而言
對於基本的類型而言的話,比如number,string,boolean等來說,確實它就是聲明一個不會變的常量,只要你修改了它,就會報錯
const a = 1
a = 2 // Uncaught TypeError: Assignment to constant variable.
const b = '1231'
b = 'xcv' // Uncaught TypeError: Assignment to constant variable.
const c = true
c = false // Uncaught TypeError: Assignment to constant variable.
對引用類型而言
不過,對於引用類型而言的話,它指的並不會對象的內容不變,而是對象的地址不變。也就是說,你可以修改對象的內部成員,但是你不可以修改該變量的地址。
const obj = {
name: 'cjg'
}
obj.school = 'sysu'
console.log(obj) // Object {name: "cjg", school: "sysu"}
obj = {} // VM183:6 Uncaught TypeError: Assignment to constant variabl
其實,就我個人理解,const無論是作用於基本類型還是引用類型,它都是為了保證變量的地址不發生改變(因為你對基本類型而言,你給它賦一個新值,其實也就意味着修改了該變量的地址)