{
var foo='foo'; let bar='bar'; } console.log(foo,'var'); //foo var
console.log(bar ,'bar');//Uncaught ReferenceError: bar is not defined
在代碼中,使用var申明的變量在代碼塊外面能被識別,可是let命令卻不能被識別,這樣就實現了js的塊級做用域,咱們在使用條件語句 循環語句等就會不擔憂變量污染的問題了,如下是兩種寫法等對比:javascript
es6:java
for (let i = 0; i < a.length; i++) { let x = a[i] … } for (let i = 0; i < b.length; i++) { let y = b[i] … } let callbacks = [] for (let i = 0; i <= 2; i++) { callbacks[i] = function () { return i * 2 } } callbacks[0]() === 0 callbacks[1]() === 2 callbacks[2]() === 4
es5:es6
var i, x, y; for (i = 0; i < a.length; i++) { x = a[i]; … } for (i = 0; i < b.length; i++) { y = b[i]; … } var callbacks = []; for (var i = 0; i <= 2; i++) { (function (i) { callbacks[i] = function() { return i * 2; }; })(i); } callbacks[0]() === 0; callbacks[1]() === 2; callbacks[2]() === 4;
在{}用let聲明的變量只有在{}內是有效的 函數
熟悉js開發的都知道函數有兩種聲明方式es5
a(); // 'a' b(); // 報錯不是一個函數 實際上是undefined
function a(){ console.log('a'); } var b=function(){ console.log('b'); }
這兩種方式js解析順序是不同的, 首先函數a會被js加載而後執行 var b ;至於b是什麼數據會等第二批執行,也就是正常按照從上到下執行代碼,在執行b()的時候仍是未初始化的狀態可是並無報錯由於var已經被優先執行了 這種就是變量提高,此時咱們修改下代碼spa
a(); // 'a' b(); // b is not defined function a(){ console.log('a'); } let b=function(){ console.log('b'); }
雖然還是報錯可是明顯提示不存在b變量了,因此使用了let以後就不會優先執行了也會迴歸「第二批」執行的隊伍中,function a(){} 依然是「第一批」優先執行的代碼。blog
js是存在做用域鏈的,在特定做用域下只能獲取同級或者高層級的變量;可是let存在變量綁定行爲,不遵循做用域鏈;ip
let a=1; (function (){ a=2; //a is not defined let a; console.log(a); }()); let a=1; (function (){ a=2; console.log(a); //2 }());
咱們能夠這樣理解,在當前執行的做用域內若是沒有對變量定義 則會從高層級級獲取,若是已經存在則封閉當前做用域再也不考慮高層級是否聲明瞭該變量;作用域
在相同做用域內,let是不能重複聲明同一個變量的;可是var則不在意聲明多少次,永遠都是後者替換前者;開發
var foo=123; var foo=456; console.log(foo); //456 let bar=123; let bar=456; //Identifier 'bar' has already been declared console.log(bar);
有了塊級做用域咱們不再用寫匿名函數來進行做用域封閉了,之前你多是這樣寫:
(function () { var foo = function () { return 1; } foo() === 1; (function () { var foo = function () { return 2; } foo() === 2; })(); foo() === 1; })();
可是如今不用這樣麻煩了,你徹底能夠這樣寫:
{ function foo () { return 1 } foo() === 1 { function foo () { return 2 } foo() === 2 } foo() === 1 }
參考了了阮一峯的介紹 作了一些簡化和本身的例子 歡迎補充~