es6 新增 let 與 var 比較
用var的不足之處
不足一
var arr = [ ];
for(var i=0; i<10; i++){
arr [i] = function(){
alert(i)
}
}
arr [8](); //結果:10
看程式碼,不難猜測程式碼的意圖是想給陣列a的元素賦值,每一個元素是一個函式,執行後彈出相對應的數字,比如:執行arr8;想alert出一個數字8,執行arr1; 想alert出一個數字1,依次類推。但是結果並不是我們預想的那樣。執行後實際彈出的是10;不管你執行的是arr[8]還是arr[5],或者是陣列內的其他元素,都是alert出一個數字:10。但這並不是我們想要的(不要說你故意這麼寫的,就是想彈出10就好了),為什麼是10呢(往下讀,有解釋)?至少目前我們可以知道了這是var不足的地方。
用let替換var之後 完美解決塊級作用域問題
var arr = [ ];
for(let i=0; i<10; i++){
arr[i] = function(){
alert(i)
}
}
arr[8](); //結果:8
這是因為let宣告的變數僅僅在自己的塊級作用域起作用,出了這個塊級作用域就不起作用。
任何一對花括號 { } 中的語句都屬於一個塊,在花括號裡面用let定義的所有變數在花括號外都是不可見的,我們稱之為塊級作用域。
不足二
用var 宣告變數的時候會出現“變數提升“的現象。
var a = 1; (function(){ alert(a); var a = 2; })();//結果:undefined 實際執行順序如下 var a = 1; (function(){ var a; alert(a); a = 2; })();
用let關鍵字來定義a;這樣a在程式碼塊內就不會提升了。那為什麼又報錯了呢,因為用let宣告的變數,在其塊級作用域內是封閉的,是不會受到外面的全域性變數a影響的,並且要先宣告再使用,所以a的值即不是1(因為不受外面的影響),也不是undefined(因為先聲明後使用),更不是2,未宣告定義就使用,只有報錯啦。
var a = 1;
(function(){
alert(a);
let a = 2;
})(); // 結果:報錯a未定義
使用let 需要注意
*在同一塊級作用域下,不允許重複宣告同一個變數
{ var a =1; let a =2; //報錯,因為a已經用var宣告過 } { let a =1; let a= 2; //還是報錯,a已經用let宣告過。 }
*函式內不能用let重新宣告函式的引數
function say(word){
let word = 'hello Jack'; //報錯:用let重新宣告word引數
alert(word)
}
say('hello Lili');
總結:用let宣告變數只在塊級作用域起作用,適合在for迴圈使用,也不會出現變數提升現象。同一個程式碼塊內,不可重複宣告的相同變數,不可重複宣告函式內的引數。
es6也給我們提供了另一個關鍵字constconst是constant(常量)的縮寫,const和 let一樣,也是用來宣告變數的,但是const是專門用於宣告一個常量的,顧名思義,常量的值是不可改變的。以前用var宣告的變數,想怎麼改就怎麼改,同一個變數,後面的值可以輕鬆覆蓋原來的值,這次const宣告的變數,可由不得我們這麼任性地想改就改了。
const有以下幾個特點
1.不可修改
2.只有塊級作用域起作用
3.不存在變數提示,必須先聲明後使用
4.不可重複宣告同一個變數
5.聲明後必須賦值
常量還可以是一個物件,這裡在賦值過程中,我們可以分為傳值賦值和傳址賦值。
傳址:在賦值過程中,變數實際上儲存的是資料的地址(對資料的引用),而不是原始資料或者資料的拷貝。
用const來宣告一個物件型別的常量,就是傳址賦值。而不可修改的是物件在記憶體中的地址.我們修改的都是物件身上的屬性,所以並沒有違背常量不可修改的約定。
總結:const也是用於宣告一個常量,並必須賦值,聲明後不可修改,跟let一樣,只在塊級作用域起作用,不可重複宣告同一個變數,不會變數提升,宣告引用型別的常量時,要注意是傳址賦值。