Javascript?中?var?和?let?、const?的區(qū)別及使用方法
1.var、let、const簡(jiǎn)介
ECMAScript 變量是松散類型的,意思是變量可以用于保存任何類型的數(shù)據(jù)。每個(gè)變量只不過(guò)是一個(gè)用于保存任意值的命名占位符。有三個(gè)關(guān)鍵字可以聲明變量:var、let、const。其中 var 在ECMAScript 的所有版本中都可以使用,而 const 和 let 只能在ECMAScript 6 及更高版本中使用。
var 聲明
var 關(guān)鍵字在定義變量中定義和使用中不嚴(yán)格。
1.定義單個(gè)變量和同時(shí)定義多個(gè)變量,在定義多個(gè)變量時(shí)用逗號(hào)隔開。兩者不賦值操作。
<script>
var userName;
var age,address,phone;
console.log(userName)
console.log(age)
console.log(address)
console.log(phone)
</script>顯然這樣輸出的值為 undefined 類型。

2.定義單個(gè)變量和同時(shí)定義多個(gè)變量,在定義多個(gè)變量時(shí)用逗號(hào)隔開。兩者賦值操作。
<script>
var userName = 'sa'
var age = 18,address = '南昌',phone = '19238824523'
console.log(userName)
console.log(age)
console.log(address)
console.log(phone)
</script>
3.var重復(fù)聲明變量和賦值
在 ECMAScript 中 var 關(guān)鍵字聲明的變量可以重復(fù)聲明,但是賦值操作會(huì)覆蓋前面已經(jīng)給變量賦的值。值不僅可以改變數(shù)據(jù)也可以改變相關(guān)的數(shù)據(jù)類型。
<script> var userName = 'sa' console.log(userName) var userName = 77 // 這邊也可以省略var console.log(userName) </script>

4.var 聲明的作用域問(wèn)題
var聲明的全局變量全局作用域會(huì)掛載到 window 對(duì)象上,可以使用window. 的形式訪問(wèn)該變量,或者直接使用變量名的方式。在函數(shù)體內(nèi)部的用var聲明的變量是局部變量,當(dāng)省略 va r時(shí),當(dāng)前變量會(huì)定義為全局變量,但是當(dāng)我要得到這個(gè)變量的值時(shí),我們需要先執(zhí)行一下函數(shù)。
<script>
// 定義函數(shù),測(cè)試兩個(gè)變量是否在函數(shù)體外部可以使用
function test(){
var msg = '這是局部變量'
message = '這是全局變量'
}
test()
console.log(window.message)
console.log(message)
console.log(msg)
</script>輸出結(jié)果如下:message 可以獲得,但是 msg 不行。關(guān)鍵問(wèn)題在于,使用 var 聲明的變量會(huì)成為包含它在函數(shù)的局部變量。在一個(gè)函數(shù)內(nèi)部定義了一個(gè)變量,就意味著該變量將在函數(shù)退出時(shí)被銷毀。

5.var 聲明提升
“提升”,也就是把所有的變量聲明都拉到函數(shù)作用域的頂部。此外,反復(fù)多次使用 var 聲明同一個(gè)變量也沒(méi)有問(wèn)題。
<script>
// 定義函數(shù),測(cè)試變量提升
function test(){
console.log(msg)
var msg = '變量'
console.log(msg)
}
test()
</script>正常的我們會(huì)認(rèn)為,變量未定義先使用,會(huì)報(bào)一個(gè) ~~ is not defined 的錯(cuò)誤。但是 var 存在變量提升的行為,以上代碼等同于:
function test(){
var msg
console.log(msg)
msg = '變量'
console.log(msg)
}
test()兩者的輸出結(jié)果都是如下:

let 聲明
let和var的作用差不多,但是有著非常重要的區(qū)別。最明顯的區(qū)別就是,let 聲明的范圍是塊作用域,而 var 聲明的范圍是函數(shù)作用域。
代碼塊由一個(gè)左花括號(hào)( { )和一個(gè)右花括號(hào)( } )標(biāo)識(shí)結(jié)束。
1.簡(jiǎn)單示意 let 和 var 的區(qū)別
// let 和 var 的作用域區(qū)別
if (true) {
var username = 'sa'
let msg = 'ss'
}
console.log(username)
console.log(msg)在當(dāng)前代碼中,let 定義的 msg 只作用與 if 的代碼塊中,在外部無(wú)法使用 msg 該變量。

2. let 不可以重復(fù)聲明變量,var 可以重復(fù)聲明變量
<script> var userName var userName let msg let msg </script>
這里提示 msg 重復(fù)定義:
![]()
3.將 let 和 var 混合重復(fù)定義一個(gè)變量
<script> var userName let userName let msg var msg // 這邊將會(huì)報(bào)一個(gè)重復(fù)定義的錯(cuò)誤 </script>
![]()
當(dāng)然,JavaScript 引擎會(huì)記錄用于變量聲明的標(biāo)識(shí)符及其所在的塊作用域,因此嵌套使用相同的標(biāo)識(shí)符不會(huì)報(bào)錯(cuò),因?yàn)橥粋€(gè)塊中沒(méi)有重復(fù)聲明。
<script>
let age = 20
console.log(age) // 20
if (true) {
let age = 18
console.log(age) // 18
}
</script>4.let 聲明的變量不會(huì)在作用域中被提升
<script>
function test() {
console.log(age)
let age = 20
}
test()
</script>
let 聲明的變量不會(huì)在作用域中被提升是和 var 一個(gè)很重要的區(qū)別。所以 let 聲明變量,必須要先聲明后使用,否則報(bào)錯(cuò)。
在解析代碼時(shí),JavaScript 引擎也會(huì)注意在塊后面的 let 聲明,只不過(guò)在此之前不能以任何方式來(lái)引用未聲明的變量。在 let 聲明之前的執(zhí)行瞬間被稱為“暫時(shí)性死區(qū)”,在此階段引用任何后面才聲明的變量都會(huì)拋出 ReferenceError。
5.let的全局聲明不會(huì)成為 window 對(duì)象的屬性( var 聲明的變量則會(huì))
<script> var msg = '我是var聲明的變量' let mess = '我是let聲明的變量' console.log(window.msg) console.log(window.mess) </script>

6.條件聲明
在使用 var 聲明變量時(shí),由于聲明會(huì)被提升,JavaScript 引擎會(huì)自動(dòng)將多余的聲明在作用域頂部合并為一個(gè)聲明。因?yàn)?let 的作用域是塊,所有不可能檢查是否已經(jīng)使用了 let 聲明過(guò)同名變量,同時(shí)也就不可能在沒(méi)有聲明的情況下使用它。
錯(cuò)誤示范如下:
<script>
// 當(dāng)前聲明兩個(gè)變量
var msg = '我是var聲明的變量'
let mess = '我是let聲明的變量'
</script>
<script>
var msg = 'sa' // 這里沒(méi)問(wèn)題,var 存在變量提升聲明來(lái)處理
let mess = 'ss' // 當(dāng)之前聲明了變量mess,這里將報(bào)錯(cuò),let 不存在變量提升
</script>![]()
<script>
let mess // 當(dāng)前只聲明了一個(gè) let 變量
</script>
<script>
if (typeof mess === 'undefined'){
let mess
}
mess = 'sa' // mess 被限制在 if {} 作用域塊中,當(dāng)前賦值為全局賦值
console.log(mess) // sa
try {
console.log(age)
}
catch (error) {
let age
}
age = 20 // age 被限制在 catch {} 作用域塊中,當(dāng)前賦值為全局賦值
console.log(age) // 20
</script>
注:條件聲明比較難以理解,這是一種反模式。這會(huì)讓我們的程序變得更加難理解。
7.for循環(huán)中的 let 聲明
當(dāng)我們?cè)谟?var 時(shí),for循環(huán)定義的迭代變量會(huì)滲透到循環(huán)體外部。
for (var i = 0; i < 6; i++) {
setTimeout(() => {
console.log(i) },0) // 這將打印六個(gè) 6
}![]()
這種原因的出現(xiàn)情況是因?yàn)橛捎?var 聲明的變量不存在塊級(jí)作用域在退出循環(huán)時(shí),迭代變量保存的是導(dǎo)致循環(huán)退出的值:6。在之后執(zhí)行超時(shí)邏輯時(shí),所有的 i 都是同一個(gè)變量,最終導(dǎo)致輸出的值相同。
使用 let 聲明 i 時(shí):
for (let i = 0; i < 6; i++) {
setTimeout(() => {
console.log(i) },0) // 這將打印六個(gè) 6
}
當(dāng)使用let 聲明變量時(shí),JavaScript 引擎在后臺(tái)會(huì)為每一個(gè)迭代循環(huán)聲明一個(gè)新的迭代變量,每個(gè) setTimeout 引用的都是不同的變量實(shí)例,所以輸出的值不同也就是我們期望中的值,也是循環(huán)執(zhí)行過(guò)程中每一個(gè)迭代變量的值。
在我們對(duì)dom節(jié)點(diǎn)使用for循環(huán)綁定事件時(shí),一般也是用 let 聲明迭代變量。
const 聲明
const 的行為和 let 基本相同,唯一一個(gè)重要的區(qū)別就是它在聲明變量的同時(shí)必須初始化變量,且嘗試修改 const 聲明的變量會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。
1.const 聲明的變量不允許修改
<script> const age = 20 age = 30 </script>

2.const 也是不可重復(fù)聲明
<script> const age = 20 const age = 30 </script>
![]()
3.const 聲明的作用域也是塊
<script>
if (true) {
const age = 30
}
console.log(age)
</script>
4.const 中注意的點(diǎn)
const 聲明限制只適用于它指向變量的引用。換句話說(shuō),如果 const 變量引用的是一個(gè)對(duì)象,那么修改這個(gè)對(duì)象內(nèi)部的值不違反 const 的限制。引用未發(fā)生改變就行。
例如:修改了對(duì)象中 name 的值但不會(huì)報(bào)錯(cuò)。
const student = {
name: 'sa',
age: 18,
address: 'shanghai'
}
student.name = 'saa'
console.log(student.name) // 輸出saa如果你想用const 聲明一個(gè)不會(huì)被修改的 for 循環(huán)變量,那也是可以的。也就是說(shuō),每次迭代只是創(chuàng)建一個(gè)新變量。這對(duì) for-in 和 for-of 循環(huán)都是有意義的。
例如:
for (const key in { a: 1, b: 2, c: 3 }){
console.log(key)
}
總結(jié)
在我們?nèi)粘J褂米兞柯暶鲿r(shí),遵循一下幾點(diǎn):
1.不使用 var
2.const 優(yōu)先,let 次之
到此這篇關(guān)于Javascript 中 var 和 let 、const 的區(qū)別以及具體使用效果的文章就介紹到這了,更多相關(guān)js中var和 let 、const 區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊左上角滑動(dòng)菜單效果代碼
這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊左上角滑動(dòng)菜單效果代碼,涉及JavaScript基于鼠標(biāo)事件動(dòng)態(tài)變換頁(yè)面元素樣式的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
JS實(shí)現(xiàn)的新浪微博大廳文字內(nèi)容滾動(dòng)效果代碼
這篇文章主要介紹了JS實(shí)現(xiàn)的新浪微博大廳文字內(nèi)容滾動(dòng)效果代碼,可實(shí)現(xiàn)頁(yè)面圖文元素定時(shí)滾動(dòng)的效果,涉及JavaScript時(shí)間函數(shù)定時(shí)改變頁(yè)面元素的相關(guān)技巧,需要的朋友可以參考下2015-11-11
克隆javascript對(duì)象的三個(gè)方法小結(jié)
克隆javascript對(duì)象的三個(gè)方法整理,需要的朋友可以參考下。2011-01-01
基于redis的小程序登錄實(shí)現(xiàn)方法流程分析
這篇文章主要介紹了基于redis的小程序登錄實(shí)現(xiàn)流程分析,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
如何利用js實(shí)時(shí)監(jiān)聽input輸入框值的變化
在做web開發(fā)時(shí)候很多時(shí)候都需要即時(shí)監(jiān)聽輸入框值的變化,以便作出即時(shí)動(dòng)作去引導(dǎo)瀏覽者增強(qiáng)網(wǎng)站的用戶體驗(yàn)感,這篇文章主要給大家介紹了關(guān)于如何利用js實(shí)時(shí)監(jiān)聽input輸入框值的變化,需要的朋友可以參考下2024-02-02
JavaScript日期工具類DateUtils定義與用法示例
這篇文章主要介紹了JavaScript日期工具類DateUtils定義與用法,涉及javascript針對(duì)日期時(shí)間的獲取、轉(zhuǎn)換、比較、運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下2018-09-09
實(shí)例說(shuō)明為什么不要行內(nèi)使用javascript
不要行內(nèi)寫js是因?yàn)檫@樣很不安全,因?yàn)橛没鸷膄irebug可以輕松讓代碼失效,下面告訴大家為什么2014-04-04
ECMAScript6函數(shù)默認(rèn)參數(shù)
這篇文章主要介紹了ECMAScript6函數(shù)默認(rèn)參數(shù)的相關(guān)資料,需要的朋友可以參考下2015-06-06

