天天看點

Js變量:var,let,const三個關鍵字的差別

Js變量:var,let,const三個關鍵字的差別

var在ECMAScript的所有版本中都可以使用,而const和let隻能在ES6及更晚的版本中使用。

var,let,const三個關鍵字的差別

var:

1)聲明作用域:在函數内部,使用var定義一個變量(局部變量),在函數被調用完之後,該變量會被立即銷毀。在定義變量時如果省略var,就會建立一個全局變量(不建議在局部作用域中定義全局變量,難維護,而且在嚴格模式下,會導緻抛出ReferenceError)。

2)聲明提升:把所有變量聲明都拉到函數作用域的頂部。

function foo(){
    console.log(age);
    var age = 18;
}      

等價于

function foo(){
    var age;
    console.log(age);
    age = 18;
}
foo();//undefined      

3)可以反複多次使用var聲明同一個變量。

function foo(){
var age = 16;
var age = 1;
var age = 2;
console.log(age);
}
foo();//2      

4)全局聲明:使用var在全局作用域中聲明的變量會成為window對象的屬性。

var age = 18;console.log(window.age);//18      

let:

1)聲明作用域:let聲明的是塊作用域,而var聲明的是函數作用域。塊作用域是函數作用域的子集,是以var作用域的限制同時也适用于let。

//var
if(true){
    var age = 18;
    console.log(age);//18
}
console.log(age);//18


//let
if(true){
    let age = 18;
    console.log(age);//18
}
console.log(age);//ReferenceError:age沒有定義      

2)聲明提升:let聲明的變量不會在作用域中被提升

3)不可以在一個塊中反複多次使用let聲明同一個變量

let age;
let age;//SyntaxError,辨別符age已經聲明過了      

4)全局聲明:使用let在全局作用域中聲明的變量不會成為window對象的屬性,但是var聲明的變量會。

let age = 18;
console.log(window.age);//undefined      

5)條件聲明:在使用var聲明變量時,由于聲明會被提升,js會自動将多餘的聲明在作用域頂部合并為一個聲明。而因為let的作用域是塊,是以不可能檢查前面是否已經使用let聲明過同名變量。是以對于let,不能依賴條件聲明模式。

6)for循環中的let聲明:在用let聲明疊代變量時,js在背景會為每個疊代變量聲明一個新的疊代變量,每個setTimeout引用的都是不同的疊代變量。for-in 和for-of都适用。

for(var i=0;1<5;i++){}
console.log(i);  //5


for(let i=0;1<5;i++){}
console.log(i);  //ReferenceError:i沒有定義      
for(var i=0;1<5;i++){
    setTimeout(()=>console.log(i),0);
}
//會輸出5,5,5,5,5


for(let i=0;1<5;i++){
    setTimeout(()=>console.log(i),0);
}
//會輸出0,1,2,3,4      

const:

1)const的行為和let基本相同,唯一的差別是const它聲明變量時必須同時初始化變量,且嘗試修改const聲明的變量會導緻運作時錯誤(TypeError)。

2)不允許重複聲明

3)作用域也是塊

4)const聲明的限制隻适用于它指向的變量的引用。換句話說,如果const變量引用的是一個對象,那麼修改這個對象内部的屬性并不違反const的限制。

const person = {};
person.name = "QiuYing";      

5)不能用const聲明疊代變量,因為疊代變量會自增。但是可以聲明一個不會被修改的for循環變量。這對for-in 和for-of循環特别有意義。

 聲明風格及最佳實踐:先使用const,let次之,不使用var。

Js變量:var,let,const三個關鍵字的差別