在es6以前咱們咱們聲明一個變量用var如:javascript
var a = 1; var arr = [1,2,3]; ...
es6以前呢javascript沒有塊級做用域,如何來理解呢:就是在代碼塊裏聲明的變量會「變量提高」至就近的函數做用域頂部或全局當中。如咱們熟悉的for循環:java
for( var i=0; i<10; i++){ console.log(i) } # 提高到全局,至關於 var i; for(i=0; i<10; i++){ console.log(i) } function test (){ ..... for( var i=0; i<10; i++){ console.log(i) } } # 提高到函數做用域頂部,至關於 function test (){ var i; ..... for(i=0; i<10; i++){ console.log(i) } }
在es6中給出了塊級做用域的概念:{}所包涵的代碼塊就是一個做用域。同時又給出了另外兩個變量聲明的關鍵字:let和const。es6
let與var同樣,也是用來聲明變量的,但它有着更好的做用域規則。來看幾個栗子:函數
function test1(){ for(var i=1;i<3;i++){ console.log(i); } console.log(i); // 3 } test1(); function test2(){ for(let i=1;i<3;i++){ console.log(i); } console.log(i); // 報錯了 } test2();
執行test1的時候,因爲變量提高了所已外面的log能找到i,而test2用的let聲明的變量,在for循環的代碼塊內生效,for循環結束後變量被銷燬,被垃圾回收機制回收。因此會報錯。code
let另一個值得注意的是,不能重複聲明變量:對象
let a = 1; let a = 3; // 報錯 Uncaught SyntaxError: Identifier 'a' has already been declared
與let不一樣之處在於,const聲明的變量只能夠在聲明時賦值,不可隨意修改,不然會致使語法錯誤。ip
const PI=3.1415926; //ok const G; G = 9.8; // SyntaxError: Missing initializer in const declaration const MODIFY = 1; MODIFY = 2; // TypeError: Assignment to constant variable.
上面能夠看到聲明的時候必須賦值不然回報沒有初始化的錯誤,已賦值的常量再次賦值也會報錯。
咱們怎麼理解下面這段代碼呢作用域
function test(){ const obj={ name: 'lilei' } obj.age=20; console.log(obj); // {name: "lilei", age: 20} } test()
const聲明的變量不是不能修改嗎,這裏怎麼能夠修改爲功呢,咱們知道對象是引用類型,咱們修改的是值,而不是其引用,而const聲明的對象類型的變量保存的是其引用,因此是不矛盾的。it