var異步
若是使用關鍵字 var 聲明一個變量,那麼這個變量就屬於當前的函數做用域,若是聲明是發生在任何函數外的頂層聲明,那麼這個變量就屬於全局做用域。函數
let
一、let 聲明的變量具備塊做用域的特徵。
二、在同一個塊級做用域,不能重複聲明變量。
function foo(){
let a = 1;
let a = 2;//Uncaught SyntaxError: Identifier 'a' has already been declared
}spa
三、let 聲明的變量不存在變量提高,換一種說法,就是 let 聲明存在暫時性死區(TDZ)。線程
for (var i = 0; i < 5; i++) {
setTimeout(function(){
console.log(i);
},100)
};
會打印4個4 :setTimeout是異步執行的,100毫秒後向任務隊列裏添加一個任務,只有主線上的所有執行完纔會執行任務隊列裏的任務,因此當主線程for循環執行完以後 i 的值爲5,這個時候再去任務隊列中執行任務,i所有爲5;每次for循環的時候setTimeout都會執行,可是裏面的function則不會執行被放入任務隊列,所以放了5次;for循環的5次執行完以後不到1000毫秒;1000毫秒後所有執行任務隊列中的函數,因此就是輸出五個5啦生命週期
for (let i = 0; i < 5; i++) {
setTimeout(function(){
console.log(i);
},100)
};
會打印0,1,2,3,4:假如把var換成let,那麼輸出結果爲0,1,2,3,4;由於let i 的是區塊變量,每一個i只能存活到大括號結束,並不會把後面的for循環的 i 值賦給前面的setTimeout中的i;而var i 則是局部變量,這個 i 的生命週期不受for循環的大括號限制;隊列
const作用域
聲明方式,除了具備 let 的上述特色外,其還具有一個特色,即 const 定義的變量,一旦定義後,就不能修改,即 const 聲明的爲常量。io
const obj = {a:1,b:2};
console.log(obj.a);//1
obj.a = 3;
console.log(obj.a);//3console
因此準確的說,是 const 聲明建立一個值的只讀引用。但這並不意味着它所持有的值是不可變的,只是變量標識符不能從新分配。for循環