簡述
- var
- 作用域:函數;可以重新分配;可以修改;同一作用域可以重複聲明
- let
- 作用域:塊級;可以重新分配;可以修改;同一作用域不能重複聲明
- const
- 作用域:塊級;不能重新分配;可以修改;同一作業域不能重複聲明
詳細介紹
var
var沒有塊級作用域,由它聲明的變量的作用域要麼是一個函數要麼就是全局的
關於聲明變量和非聲明變量
- 聲明變量的作用域限制在聲明位置的上下文中,非生命變量的作用域總是全局的
- 聲明變量在任何代碼執行前創建,而非聲明代碼只有在賦值時被創建
聲明變量上下文環境中的不可配置屬性,而非聲明變量是可配置屬性
嚴格模式下非聲明變量會出錯變量提升
變量的聲明會被提升到其作用域的開頭被處理,這就是變量提升。但是此時的處理只是聲明瞭變量,對於var聲明的變量而言,會在此時被賦值爲undefine,而對變量的賦值只有在執行到該聲明語句時纔會被執行
console.log(a);//undefine
var a=2;
console.log(a);//2
多個變量的初始化
function f(){
var x=y=2;//x在函數中被聲明,而y是全局變量;
};
let
let與var一樣聲明時同樣會有變量提升,但不同的是此時變量是無法訪問的,如果此時訪問變量就會報錯,這也就是所謂的暫存死區的問題
更多關於暫存死區的問題請訪問這裏(要注意的是聲明變量時,一條語句中依然是順序執行的)
console.log(a);//ReferenceError
let a=2;
console.log(a);//2
const
const聲明的變量相當於一個常量,但它並不是不可改變的,當你聲明的是一個數組或對象時
const x=b[];
x=a[];//error
const x=b[];
b.push(1);
console.log(x[0]);//1
const obj={name:"John"};
obj.age=20;
obj.name="Peter";
console.log(obj.name+obj.age);//"Peter20"
函數的聲明
函數同樣也會提升,可以在函數定義之前使用函數
var b=foo();
console.log(b);//1
console.log(foo);//function foo
function foo(){
var a=4;
return 1;
};
var foo=2;
console.log(foo);//2
從上面的代碼可以看出函數的提升優先於變量