簡(jiǎn)單談?wù)剛€(gè)人對(duì)變量聲明關(guān)鍵字var、let、const的理解。
初次寫(xiě)文,不夠清晰嚴(yán)謹(jǐn),還望體諒;錯(cuò)誤之處還望指正。
變量聲明的兩個(gè)步驟:
- 定義(defined)
- 初始化(initialize)
var a // 定義變量a,并且初始化a為undefined
console.log(a) // output: undefined
一般來(lái)說(shuō),默認(rèn)的變量聲明還包括第三部:賦值(assignment),賦值的過(guò)程是將變量指向內(nèi)存地址的過(guò)程
var a = 1 // 定義變量a,初始化為undefined,將a賦值為1,a指向1所在的內(nèi)存地址
console.log(a) // output: 1
以下提到的變量聲明均包含賦值的步驟。
Var、Let和Const三者的不同點(diǎn):
- var聲明的變量在全局范圍內(nèi)有效,let和const聲明的變量只在當(dāng)前作用域內(nèi)有效。
“全局范圍”是指當(dāng)前js頁(yè)面,不是全局變量“global”;“當(dāng)前作用域”是指當(dāng)前聲明地址所在的范圍,一般指中括號(hào)包含的區(qū)域,立即執(zhí)行函數(shù)除外。
{
var a = 1
let b = 2 // 當(dāng)前作用域?yàn)榍昂髢蓚€(gè)中括號(hào)之間
}
console.log(a) //output:1
console.log(b) //ReferenceError: b is not defined
- var聲明的變量存在變量提升,變量的聲明(定義和初始化,不包含賦值)會(huì)提升至最頂部,如下,變量x先賦值,再使用,最后聲明,輸出了正常結(jié)果,聲明的位置沒(méi)有影響。
x = 1
console.log(x) // expectedoutput:1
var x
let和cosnt沒(méi)有變量提升,并且在當(dāng)前作用域內(nèi)有暫時(shí)性死區(qū),當(dāng)前作用域內(nèi)聲明之前調(diào)用會(huì)報(bào)錯(cuò)。
//(暫時(shí)性死區(qū))
console.log(y) // ReferenceError: y is not defined
let y = 2
var a = 1
{
//(暫時(shí)性死區(qū))
console.log(a) // ReferenceError: a is not defined
let a = 2
console.log(a) // expected output: 2
}
console.log(a) // expected output: 1
- var聲明的變量可以再次聲明和賦值。
var a = 1
console.log(a) // output: 1
var a = 2
console.log(a) // output: 2
let聲明變量后不可再次聲明,可以再次賦值。
let a = 1
console.log(a) // output: 1
a = 2
console.log(a) // output: 2
//不可重復(fù)聲明
var a = 3 // SyntaxError: Identifier 'a' has already been declared
const聲明的變量之后不可再次聲明和賦值(但是變量的值可以改變,下方說(shuō)明)。
const A = 1
//不可重復(fù)賦值
A = 2 // TypeError: Assignment to constant variable.
//不可重復(fù)聲明
var A = 2 // SyntaxError: Identifier 'A' has already been declared
注:當(dāng)const聲明的變量為引用類(lèi)型的時(shí)候,變量的值可以改變,引用類(lèi)型和基本類(lèi)型說(shuō)明見(jiàn)附錄。
const A = {
name:'Tom'
}
A.name = 'Lily'
console.log(A) // output: { name: 'Lily' }
附錄:
基本(原始)數(shù)據(jù)類(lèi)型(primitive data type):
Undefined、Null、Number、Boolean、String和Symbol(bigint在后續(xù)ES版本的標(biāo)準(zhǔn)中添加)
//例如:
123
0b10
"asd"
true
undefined
null
Symbol(1)
- 基本數(shù)據(jù)類(lèi)型存儲(chǔ)在棧內(nèi)存(Stack)中
- 基本數(shù)據(jù)類(lèi)型的比較是值的比較
var a = 1
var b = 1
console.log(a===b) // output:true
console.log(1===true) // output:false
- 基本數(shù)據(jù)類(lèi)型的值是不可以改變的
var a = '111'
a.toUpperCase()
a[0] = '0'
console.log(a) // output: "111"
引用數(shù)據(jù)類(lèi)型:
Object
這里的Object是引用數(shù)據(jù)類(lèi)型對(duì)象的籠統(tǒng)稱(chēng)呼,包含Object、Array、Function以及用new關(guān)鍵字生成的Number、Boolean、String類(lèi)型等
- 引用數(shù)據(jù)類(lèi)型存在堆內(nèi)存(Heap)中
- 引用數(shù)據(jù)類(lèi)型的比較是內(nèi)存地址的比較
var a = {name:"Tom"}
var b = {name:"Tom"}
//a和b在內(nèi)存中的地址不一樣
console.log(a===b) // output: false
- 引用數(shù)據(jù)類(lèi)型的值可以改變
var a = {name:"Tom"}
a.name = "Lily"
//a所指向的內(nèi)存地址沒(méi)有改變
console.log(a) // output: {name:"Lily"}
到這里就很好理解了,const聲明的變量的所指向的內(nèi)存地址不可以改變,當(dāng)const聲明的變量指向基本數(shù)據(jù)類(lèi)型時(shí),變量的值不可以再改變,當(dāng)const聲明的變量指向引用數(shù)據(jù)類(lèi)型時(shí),變量的值可以改變。