let myName = 'luoxue'; let age = 25;
let
語句容許申明一個做用域被限制在代碼塊內的變量、語句或表達式。git
{ let myName = 'luoxue'; } console.log(myName); // myName is not defined
之因此報錯 ,是由於 let
所申明的變量只在 let
語句所在代碼塊內有效;es6
var
對比{ let myName = 'luoxue'; var age = 25; console.log(myName); // luoxue } console.log(myName); // myName is not defined console.log(age); // 25
上面這段代碼能夠看到,let
的做用域是 let
語句所在代碼塊或者其子塊,而 var
的做用域則是整個封閉函數。github
let
不存在變量提高console.log(color); // color is not defined let color = 'orange'; console.log(colors); // undefined var colors = 'yellow';
只要塊級做用域內存在 let
語句,它所申明的變量就「綁定」這個區域,不受外部的影響,以下:閉包
var love = 'kk'; if(true) { love = 'kkk'; // love is not defined let love = 'k'; }
注:ES6明確規定,若是區塊內存在 let
const
語句,則這個區塊對這些語句申明的變量從一開始就造成封閉做用域,只要在申明以前實用,就會報錯,以下也會報錯:ide
{ title = 'Love you'; // title is not defined console.log(title); // title is not defined let title; console.log(title); // undefined title = 'Love kk'; console.log(title); // Love kk }
暫時性死區的本質:只要一進入當前做用域,所要實用的變量就已經存在,可是不可獲取,只有出現申明變量的那行代碼以後,才能夠獲取和實用該變量。函數
{ let yourName = 'kk'; // Identifier 'yourName' has already been declared let yourName = 'k'; }
下面的代碼書寫方式是不容許的:code
let fn = (arg) => let arg = 25; // Unexpected identifier
有一道題目以下,說明爲何 a[3]()
的結果是5,如何實現 a[3]()
的結果是3?ip
var arr = []; for(var i = 0; i < 5; i++) { arr[i] = function() { console.log(i); } } arr[3](); // 5
這裏的 i
是用的 var
申明的,那麼 i
的做用域則是全局,當用 a[3]()
調用時 i
的值隨着循環的結束已經變爲5,因此 arr[3]()
的值是5,可使用 let
語句來重構一下,以下:內存
let arr = []; for(let i = 0; i < 5; i++) { arr[i] = function() { console.log(i); } } arr[3](); // 3
由於在 for
語句裏面用 let
定義的 i
的做用域是 for
語句裏面的代碼塊,因此每次循環的 i
都是一個新的變量,都互不干擾,最後執行結果也就是對應的3,固然,這裏也能夠實用閉包的方式來實現,代碼以下:作用域
// 閉包的實現方式 var arr2 = []; for(var i = 0; i < 5; i++) { arr2[i] =(function(e) { return function() { console.log(e); } })(i); } arr2[3]();
參考:
阮一峯老師的《es6入門標準》第二章第一小節(實體書);
MDN let語句;