1.let和var類似,
(1)let與var不同的點:let沒有預編譯,變量提升這個過程,let聲明的變量只能在當前作用域內訪問到(一個{}可以看做是一個作用域),在全局var聲明的變量屬於window,而let聲明的不屬於
let a = 12; (function () { console.log(a); let a = 5; }());
可見上面代碼中是會報錯的,如果a是var聲明的,那么就不會報錯、輸出a的值是undefined
(2)雖然說let聲明的變量不允許重復聲明,但是在for循環中貌似又是可以的

for (let i = 0; i < 10; i++) { let i = "abc"; console.log(i); //這里輸出的是abc }
上面for聲明i的小括號可以看做是一個父級作用域,{}執行體可以看做是子級作用域,具體for為什么可以重復聲明我也不是很清楚。。
(3)塊級作用域{},在es6當中引入塊級作用域,每個{}都屬於一個塊級,然而每個塊級的中的變量都是相互隔離的訪問不到的

//塊級作用域 { let ooo = 13; { let ooo = 18; console.log(ooo); //18 } console.log(ooo); //13 }
{ let ooo = 13; { console.log(ooo); //報錯 (此處為死區) let ooo = 12; } console.log(ooo); }
(4)let關鍵字和var關鍵字在for中的區別

var arr = []; for (var i = 0; i < 10; i++) { arr[i]=function(){ console.log(i); } } arr[6](); //輸出的是10 var arr = []; for (let i = 0; i < 10; i++) { arr[i]=function(){ console.log(i); } } arr[2](); //輸出的是2
for循環中用var聲明的最后輸出的是10大家應該都是知道。因為在函數執行的時候i已經變成10了而為什么let聲明的卻不是10呢,是因為let聲明的變量只在本輪循環有效,所以每一次循環i都是一個新的變量,所以最后輸出的是6。有點疑惑的是,如果說每次i都是重新聲明的,那怎么知道上一輪循環的是多少,從而計算出本輪循環的值?這是因為JavaScript引擎內部會記住上一輪循環的值,初始化本輪的變量i時,就在上一輪循環的基礎上進行計算。