{ let a = 10; } console.log(a) //ReferenceError:a is not defined
let不像var那樣會發生「變量提高」現象,因此,變量必定要在聲明後使用,否則就會報錯。javascript
console.log(a) //ReferenceError:a is not defined let a = 10;
只要塊級做用域內存在let關鍵字,它所聲明的變量就綁定這個區域,再也不受外部影響。java
var tmp = 20; if(true){ tmp = 'abc'; //ReferenceError:tmp is not defined let tmp; }
上面的代碼中存在全局變量tmp,可是塊級做用域內let又聲明瞭一個局部變量tmp,致使後者綁定了這個塊級做用域,因此在let聲明變量前,對tmp賦值會報錯。函數
ES6明確規定,若是區塊中存在let和const命令,則這個區塊對這些命令聲明的變量從一開始就造成封閉做用域。只要在聲明以前使用這些變量,就會報錯。在語法上稱爲「暫時性死區(temporal dead zone,TDZ)」
code
有時候,會不經間遇到比較隱蔽的「死區」,不太容易被發現。對象
function bar(x=y,y=2){ return [x,y]; } bar() //報錯
上面的代碼中是由於參數x的默認值等於另外一個參數y,而此時y尚未聲明,屬於死區。ip
let不容許在相同的做用域內
聲明同一個變量。內存
function bar(){ let a = 10; var a = 20; } //報錯 function bat(){ let a = 10; let a = 20; } //報錯
所以,因此也不能在函數內重複聲明參數:作用域
function bar(args){ let args = 10; } bar() //報錯 function bar(args){ { let args = 20; } } bar() //不報錯
外層代碼塊不受內層代碼塊的影響。io
外層做用域沒法讀取內層做用域的變量。console
內層做用域能夠定義外層做用域的同名變量。
塊級做用域的實現,使得普遍使用的自執行匿名函數(IIFE)變得再也不必要了。
//自執行模式 (function(){ var a = 10; })() //塊級做用域寫法 function(){ let a = 10; }
函數自己的做用域也在其所在的塊級做用域以內。
const用來聲明常量。一旦聲明,其值就不能再改變。
const PI = 3.1415; const PI = 3 //TypeErrorL "PI" is read-only
const聲明的變量不得改變值,意味着const一旦聲明常量就必須當即初始化,不能留到後面賦值。
const與let關鍵字同樣,只在聲明所在的塊級做用域內有效;const關鍵字聲明的常量也不提高,一樣存在暫時性死區,只能在聲明後使用。
對於複合型數據類型,常量名不指向數據,而是指向數據所在的地址。const關鍵字只是保證常量名指向的地址不變,並不保證該地址的數據不變,因此將一個對象聲明爲常量必須注意該點。