let和const在不少工程師眼裏可能只是變量聲明符,其實錯了他仍是有不少小細節值得注意的,這裏我簡單介紹幾點。es6
在ES6以前咱們腦海裏應該只存在全局做用域和函數級做用域,沒有塊級做用域。那麼爲何要引入塊級做用域呢?面試
var str = "hello";
function d() {
console.log(str);
if (false) {
var str = 'world';
}
}
d();//undefined
複製代碼
相信不少剛入門的同窗看到上述代碼會有所不解,其實在全局做用域str變量已經被聲明且賦值,爲何我函數裏面訪問不到呢。這裏就牽扯到變量提高和函數級做用域的概念。上述代碼其實等同於下放代碼,當函數被執行的時候生成了一個新的做用域也就是函數做用域,js引擎會把變量聲明提到方法體的最前面,你們能夠看到只是聲明瞭並無賦值。因此就是 undefined。數組
var str = "hello";
function d() {
var str ;
console.log(str);
if (false) {
str = 'world';
}
}
d();//undefined
複製代碼
var str = 'hello';
for (var i = 0; i < str.length; i++) {
console.log(str[i]);
}
console.log(i); // 5
複製代碼
不少同窗面試的時候可能會遇到上面相似的代碼,疑惑點應該在爲何會打印出來爲何會是5,一樣的道理代碼如同下方。變量會被提高,因此在循環結束以後i就被累加到了5.bash
var str = 'hello';
var i;
for ( i = 0; i < str.length; i++) {
console.log(str[i]);
}
console.log(i); // 5
複製代碼
es6的let和const聲明符,是不存在變量提高的;同時也只在塊級做用域生效。微信
這個答案應該很明顯了吧函數
var str = "hello";
function d() {
console.log(str);
if (false) {
let str = 'world';
}
}
d();
複製代碼
什麼是暫時性死區呢?不少人可能很迷惑。那就聽我娓娓道來,若是說咱們使用了let和const命令,做用域內會對這些命令聲明的變量,在它的聲明週期內造成一種封閉做用域。這在語法上,稱爲「暫時性死區」。代碼展現以下:學習
if (true) {
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp;
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
複製代碼
由於let和const聲明是不會被提高的,因此爲了保障聲明的有效性,js的解釋引擎會對變量所處的塊級做用域造成一種保護,所以在聲明以前使用會有語法錯誤,是不被容許的。ui
不能重複聲明編碼
function de(){
var a = "1";
var a = "2";
console.log(a);
}
de()//不報錯
function de(){
var a = "1";
let a = "2";
console.log(a);
}
de()//報錯
function de(){
let a = "1";
let a = "2";
console.log(a);
}
de()//報錯
複製代碼
相信你們通常不會聲明重複變量編碼,因此在這裏就不作解釋了。若是你們感興趣能夠本身研究或者來現場一塊兒學習。spa
const聲明符的大多特性和let相同,這裏就很少作解釋了。你們都知道const是聲明常量的,一但變量被聲明成常量它就不能再被繼續修改了。你們要注意的是這裏變量不可被修改的是存儲的地址值不可被修改,意思就是簡單類型的數據是不能修改的。複合類型的數據(主要是對象和數組)const只能保證這個指針是固定的,而這個具體的對象實例包含的屬性是能夠被修改的。看看代碼咱們可能會更清楚:
//實例一
const a = "hello";
console.log(a);//"hello"
a = "world";//Assignment to constant variable
//實例二
const obj = {};
obj.name = "jack";
console.log(obj.name);//"jack"
obj = {};//Assignment to constant variable.
//實例三
const a = [];
a.push('Hello');
console.log(a); //[ 'Hello' ]
a.length = 0;
a = ['Dave']; // Assignment to constant variable.
複製代碼
正如你們所看到的字符串a被複制後就不能在修改,而對象和數組是能夠改變它裏面的元素的,可是不能給從新複製一個新的對象實例。由此就能夠判定const聲明出來的變量存的是固定的地址值。