let和const命令
1、let命令
2、塊級作用域
3、const命令
4、頂層對象的屬性
5、global對象
1、let命令
ES6在ES5的基礎上新增了let命令,用來聲明變量,用法類似var,但是let所聲明的變量,只在let命令所在的代碼塊內有效。
for循環的計數器,就很適合使用let命令
----計數器i只在for循環體內有效,在循環體外引用就會報錯。
----變量i是var聲明的,在全局范圍內都有效,所以每次循環,新的值就會覆蓋舊的值。
在這里要注意的是:使用let聲明的變量僅在塊級作用域內有效。ES5中沒有塊級作用域。
在其他C的語言中,由花括號封閉的代碼都有自己的作用域(如果用ECMAScript的話來講,就是它們自己的執行環境)如果是在C,C++或java中,變量會在if語句執行完畢后銷毀,但是在沒有塊級作用域的情況下,if語句中的變量聲明會將變量添加到當前的執行環境(在這里是全局環境)。
對于有塊級作用域的語句來說,for語句初始化表達式所定義的變量,只會存在于循環的環境之中。
不存在變量提升
var會發生變量提升。即變量可以在聲明之前使用。let和var的使用情況剛好相反。
暫時性死區
本質:只要進入當前作用域,所要使用的變量就已經存在了,但是不可獲取,只有等到聲明變量的那行代碼出現,才可以獲取和使用該變量。
2、塊級作用域
之所以在ES6中新增塊級作用域,是因為ES5只有全局作用域和函數作用域,帶來很多不合理的場景:
1)內層變量可能會覆蓋外層變量,原因在于變量提升導致的。
2)用來計數的循環變量泄露為全局變量。對于Javascript來說,由for語句創建的變量即使在for循環執行結束后,也依舊會存在于循環外部的執行環境中。
ES6的塊級作用域
let實際上為了JavaScript新增了塊級作用域。
ES6允許塊級作用域的任意嵌套。
{{{ let example = "hello"}
console.log( example );
}}報錯,原因:外層作用域無法讀取內層作用域的變量
內層作用域可以定義外層作用域的同名變量
{{{
let example = "hello";
{ let example = "hello" }
}}}
塊級作用域與函數聲明
ES5規定,函數聲明只能在頂層作用域和函數作用域中聲明,不能在塊級作用域聲明。
ES6引入了塊級作用域,在塊級作用域中,函數聲明語句的行為類似于let,在塊級作用域之外不可引用。
為了減輕用let產生的不兼容問題,ES6的瀏覽器可以不遵守上面的規定,有自己的規則:
----允許在塊級作用域內聲明函數。
----函數聲明類似var,即會提升到全局作用域或函數作用域的頭部。
----同時,函數聲明還會提升到所在的模塊作用域的頭部。
根據以上三條規則,在瀏覽器的ES6環境中,塊級作用域聲明的函數行為類似于var聲明的變量,但是若在塊級作用域內只聲明函數,沒定義函數(一種情況),會報錯。
如果確實需要在塊級作用域內聲明函數,也應該寫成函數表達式,而不是函數聲明結構。
還有要注意的是:ES6的塊級作用域允許聲明函數的,只在使用大括號的情況下使用。如果沒有大括號,報錯。
Do表達式
塊級作用域將兩個語句封裝在一起,let聲明變量,域外得不到變量的值,除非該變量是全局變量。
但有一個方法,在塊級作用域前加上do,變為do表達式,可以返回值。
3、const命令
const聲明一個只讀的變量,一旦聲明,常量的值就不能改變。
const的作用域與let命令相同:只能在聲明所在的塊級作用域內有效。
const命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。
const聲明的變量,也與let一樣,不可重復使用。
對于復合類型的變量,變量名不指向數據,而是指向數據所在的地址。const命令只是保證變量名指向的地址不變,并不保證該地址的數據不變。
若想凍結對象,應該使用odject.freeze方法。
新聞熱點
疑難解答