JavaScript中三種變量聲明方式var、let、const的區(qū)別與實(shí)戰(zhàn)指南
要理解 const、var、let 的區(qū)別,我們可以從 作用域、變量提升、可重復(fù)聲明、可修改性 這幾個(gè)核心維度展開(kāi),這些也是新手最容易混淆的點(diǎn)。
一、核心概念鋪墊
首先明確兩個(gè)基礎(chǔ)概念,能幫你更好理解區(qū)別:
- 函數(shù)作用域:變量只在聲明它的函數(shù)內(nèi)部可訪(fǎng)問(wèn)(
var是函數(shù)作用域)。 - 塊級(jí)作用域:變量只在聲明它的
{}內(nèi)部可訪(fǎng)問(wèn)(let/const是塊級(jí)作用域,{}包括if/for/while/ 普通代碼塊)。 - 變量提升:JS 引擎在執(zhí)行代碼前,會(huì)把變量聲明 “提升” 到當(dāng)前作用域頂部(但賦值不會(huì)提升)。
二、逐個(gè)拆解 + 對(duì)比
1. var(ES5 語(yǔ)法)
var 是 ES5 中聲明變量的方式,特性如下:
- 作用域:函數(shù)作用域(無(wú)塊級(jí)作用域)。
- 變量提升:聲明會(huì)被提升,且提升后默認(rèn)值為
undefined。 - 可重復(fù)聲明:同一作用域內(nèi)可重復(fù)聲明同一個(gè)變量,后聲明的會(huì)覆蓋前一個(gè)。
- 可修改:聲明后可隨意修改值。
示例代碼:
// 1. 函數(shù)作用域(無(wú)塊級(jí)作用域)
if (true) {
var a = 10;
}
console.log(a); // 輸出 10(a 跳出了 if 的 {},因?yàn)?var 無(wú)塊級(jí)作用域)
// 2. 變量提升
console.log(b); // 輸出 undefined(聲明提升了,賦值沒(méi)提升)
var b = 20;
// 3. 可重復(fù)聲明
var c = 30;
var c = 40;
console.log(c); // 輸出 40(后聲明的覆蓋前一個(gè))
// 4. 可修改
var d = 50;
d = 60;
console.log(d); // 輸出 60
2. let(ES6 語(yǔ)法)
let 是 ES6 為解決 var 的缺陷新增的聲明方式,特性如下:
- 作用域:塊級(jí)作用域(被
{}限制)。 - 變量提升:存在 “暫時(shí)性死區(qū)(TDZ)”—— 聲明也會(huì)提升,但提升后不會(huì)賦值
undefined,在聲明前訪(fǎng)問(wèn)會(huì)報(bào)錯(cuò)。 - 不可重復(fù)聲明:同一作用域內(nèi)不能重復(fù)聲明同一個(gè)變量(包括不能和
var/const重復(fù))。 - 可修改:聲明后可修改值。
示例代碼:
// 1. 塊級(jí)作用域
if (true) {
let a = 10;
}
console.log(a); // 報(bào)錯(cuò):a is not defined(a 被 if 的 {} 限制,外部訪(fǎng)問(wèn)不到)
// 2. 暫時(shí)性死區(qū)
console.log(b); // 報(bào)錯(cuò):Cannot access 'b' before initialization
let b = 20;
// 3. 不可重復(fù)聲明
let c = 30;
// let c = 40; // 報(bào)錯(cuò):Identifier 'c' has already been declared
// var c = 40; // 同樣報(bào)錯(cuò)
// 4. 可修改
let d = 50;
d = 60;
console.log(d); // 輸出 60
3. const(ES6 語(yǔ)法)
const 用于聲明常量,特性和 let 基本一致,核心區(qū)別是不可修改:
- 作用域:塊級(jí)作用域(和
let完全一樣)。 - 變量提升:同樣有暫時(shí)性死區(qū)(和
let完全一樣)。 - 不可重復(fù)聲明:和
let完全一樣。 - 不可修改:聲明時(shí)必須賦值,且賦值后不能修改引用(注意:如果是對(duì)象 / 數(shù)組,內(nèi)部屬性 / 元素可修改)。
示例代碼:
// 1. 塊級(jí)作用域
if (true) {
const a = 10;
}
console.log(a); // 報(bào)錯(cuò):a is not defined
// 2. 暫時(shí)性死區(qū)
console.log(b); // 報(bào)錯(cuò):Cannot access 'b' before initialization
const b = 20;
// 3. 不可重復(fù)聲明
const c = 30;
// const c = 40; // 報(bào)錯(cuò)
// 4. 聲明時(shí)必須賦值
// const d; // 報(bào)錯(cuò):Missing initializer in const declaration
// 5. 不可修改引用(重點(diǎn))
const e = 50;
// e = 60; // 報(bào)錯(cuò):Assignment to constant variable.
// 注意:對(duì)象/數(shù)組的內(nèi)部可修改(只是引用不能變)
const obj = { name: "張三" };
obj.name = "李四"; // 正常執(zhí)行,輸出 { name: '李四' }
console.log(obj);
const arr = [1, 2];
arr.push(3); // 正常執(zhí)行,輸出 [1,2,3]
console.log(arr);
三、核心區(qū)別對(duì)比表
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函數(shù)作用域 | 塊級(jí)作用域 | 塊級(jí)作用域 |
| 變量提升 | 有(提升為 undefined) | 有(暫時(shí)性死區(qū)) | 有(暫時(shí)性死區(qū)) |
| 重復(fù)聲明 | 允許 | 不允許 | 不允許 |
| 聲明后賦值 | 允許(默認(rèn) undefined) | 允許(默認(rèn)未初始化) | 不允許(必須立即賦值) |
| 修改值 | 允許 | 允許 | 引用不可改(對(duì)象 / 數(shù)組內(nèi)部可改) |
四、實(shí)際開(kāi)發(fā)中的使用建議
- 優(yōu)先用
const:聲明不需要修改的變量(如常量、固定引用的對(duì)象 / 數(shù)組),能減少代碼意外修改的風(fēng)險(xiǎn)。 - 其次用
let:聲明需要修改的變量(如循環(huán)變量、狀態(tài)變量)。 - 完全不用
var:var的函數(shù)作用域和變量提升容易導(dǎo)致 bug(比如循環(huán)變量泄露、重復(fù)聲明覆蓋),ES6 后已被let/const替代。
五、let 和 const 取代var
let 和 const 是 ES6 新增的變量聲明方式,核心是解決 var 的作用域和提升問(wèn)題,它們的使用場(chǎng)景可以用一句話(huà)概括:優(yōu)先用 const,需要修改時(shí)用 let。下面結(jié)合具體場(chǎng)景和代碼示例,幫你徹底分清什么時(shí)候用哪個(gè)。
(一)、const 的使用場(chǎng)景(優(yōu)先選擇)
const 聲明的是引用不可變的變量(聲明時(shí)必須賦值,且不能重新賦值),適合以下所有 “不需要修改值 / 引用” 的場(chǎng)景:
1. 聲明常量(固定不變的值)
比如數(shù)學(xué)常量、配置項(xiàng)、固定字符串等,用 const 能明確表示 “這個(gè)值不會(huì)變”,減少代碼意外修改的風(fēng)險(xiǎn)。
// 數(shù)學(xué)常量 const PI = 3.1415926; const RADIUS = 5; const AREA = PI * RADIUS * RADIUS; // 計(jì)算后的值也不變 // 配置項(xiàng)(固定的接口地址、密鑰等) const BASE_URL = 'https://api.example.com'; const TOKEN = 'abc123456'; // 固定字符串 const TITLE = '個(gè)人信息'; // 就像你之前寫(xiě)的標(biāo)題文本
2. 聲明不需要重新賦值的對(duì)象 / 數(shù)組
注意:const 只是限制 “引用不可變”,對(duì)象 / 數(shù)組的內(nèi)部屬性 / 元素可以修改,這種場(chǎng)景非常適合用 const(因?yàn)槟阒皇遣僮鲀?nèi)部,不會(huì)重新賦值整個(gè)對(duì)象 / 數(shù)組)。
// 個(gè)人信息對(duì)象(只會(huì)改內(nèi)部屬性,不會(huì)重新賦值)
const userInfo = {
name: '韓雨龍',
class: '24專(zhuān)本軟件',
hobby: ['唱歌', '跳舞']
};
// 允許修改內(nèi)部屬性(符合 const 規(guī)則)
userInfo.name = '小雨';
userInfo.hobby.push('爬山');
// 列表數(shù)據(jù)(只會(huì)增刪元素,不會(huì)重新賦值數(shù)組)
const list = ['蘋(píng)果', '香蕉'];
list.push('橙子'); // 正常執(zhí)行
3. 聲明 DOM 元素(創(chuàng)建后不會(huì)重新賦值)
就像你之前寫(xiě)的創(chuàng)建 h2 元素,創(chuàng)建后只會(huì)修改它的文本 / 樣式,不會(huì)重新賦值成另一個(gè)元素,所以用 const 最合適。
// 創(chuàng)建 h2 元素(不會(huì)重新賦值,用 const)
const h2 = document.createElement('h2');
h2.textContent = '個(gè)人信息'; // 只是修改屬性,不是重新賦值
document.body.appendChild(h2);
// 創(chuàng)建按鈕元素(同理)
const btn = document.createElement('button');
btn.textContent = '點(diǎn)擊';
document.body.appendChild(btn);
(二)、let 的使用場(chǎng)景(僅當(dāng)需要修改時(shí))
let 聲明的是可重新賦值的變量,只有當(dāng)你需要 “修改變量的值 / 引用” 時(shí),才用 let,常見(jiàn)場(chǎng)景如下:
1. 循環(huán)變量(值會(huì)不斷變化)
for/while 循環(huán)中的計(jì)數(shù)器(比如 i),每次循環(huán)都會(huì)修改值,必須用 let(不能用 const,因?yàn)?i++ 是重新賦值)。
// for 循環(huán)計(jì)數(shù)器(i 會(huì)從 0 變到 4,需要修改)
const info = ['班級(jí)', '學(xué)號(hào)', '姓名', '性別', '愛(ài)好'];
for (let i = 0; i < info.length; i++) {
const p = document.createElement('p');
p.textContent = info[i];
document.body.appendChild(p);
}
// while 循環(huán)變量
let count = 0;
while (count < 3) {
console.log('計(jì)數(shù):', count);
count++; // 重新賦值,必須用 let
}
2. 狀態(tài)變量(值會(huì)動(dòng)態(tài)變化)
比如開(kāi)關(guān)狀態(tài)、計(jì)數(shù)器、表單輸入值等,這些值會(huì)隨著操作(點(diǎn)擊、輸入)變化,需要用 let。
// 開(kāi)關(guān)狀態(tài)(點(diǎn)擊按鈕切換 true/false)
let isShow = false;
const btn = document.createElement('button');
btn.textContent = '顯示/隱藏';
btn.onclick = function() {
isShow = !isShow; // 重新賦值,用 let
console.log('狀態(tài):', isShow);
};
document.body.appendChild(btn);
// 計(jì)數(shù)器(點(diǎn)擊一次加 1)
let num = 0;
const countBtn = document.createElement('button');
countBtn.textContent = '計(jì)數(shù)';
countBtn.onclick = function() {
num++; // 重新賦值,用 let
countBtn.textContent = `計(jì)數(shù):${num}`;
};
document.body.appendChild(countBtn);
3. 臨時(shí)變量(需要重新賦值)
比如分步計(jì)算的值、條件判斷后需要修改的變量,這些場(chǎng)景需要多次賦值。
// 分步計(jì)算總價(jià)
let total = 0;
total += 10; // 加商品1價(jià)格
total += 20; // 加商品2價(jià)格
total *= 0.8; // 打8折(多次重新賦值,用 let)
console.log('總價(jià):', total);
// 條件賦值(根據(jù)條件修改變量)
let message = '';
const isLogin = false;
if (isLogin) {
message = '歡迎登錄';
} else {
message = '請(qǐng)先登錄'; // 重新賦值,用 let
}
(三)、避坑提醒(新手常錯(cuò))
- ? 錯(cuò)誤:用
const聲明需要修改的變量
const i = 0; i++; // 報(bào)錯(cuò):Assignment to constant variable.(const 不能重新賦值)
- ? 錯(cuò)誤:沒(méi)必要用
let聲明不修改的變量
// 標(biāo)題文本不會(huì)改,應(yīng)該用 const 而不是 let let TITLE = '個(gè)人信息';
總結(jié)
- 優(yōu)先用
const:所有不需要重新賦值的場(chǎng)景(常量、對(duì)象 / 數(shù)組、DOM 元素、固定字符串等),用const能讓代碼更安全、語(yǔ)義更清晰。 - 僅用
let:只有當(dāng)變量需要重新賦值時(shí)(循環(huán)變量、狀態(tài)變量、臨時(shí)變量等),才用let。 - 核心原則:能不用
let就不用,用const約束 “不變”,用let表示 “可變”,徹底拋棄var
以上就是JavaScript中三種變量聲明方式var、let、const的區(qū)別與實(shí)戰(zhàn)指南的詳細(xì)內(nèi)容,更多關(guān)于JavaScript變量聲明方式var、let、const的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Javascript 創(chuàng)建類(lèi)并動(dòng)態(tài)添加屬性及方法的簡(jiǎn)單實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇Javascript 創(chuàng)建類(lèi)并動(dòng)態(tài)添加屬性及方法的簡(jiǎn)單實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
前端實(shí)現(xiàn)PDF文件預(yù)覽的7種方案與性能對(duì)比詳解
這篇文章主要為大家詳細(xì)介紹了前端實(shí)現(xiàn)PDF文件預(yù)覽的7種方案與性能對(duì)比,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-03-03
JavaScript實(shí)現(xiàn)tab欄切換的效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)tab欄切換的效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
thinkphp中常用的系統(tǒng)常量和系統(tǒng)變量
這篇文章主要介紹了thinkphp中常用的系統(tǒng)常量和變量,需要的朋友可以參考下2014-03-03
原生js實(shí)現(xiàn)網(wǎng)易輪播圖效果
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)網(wǎng)易輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
JavaScript正則表達(dá)式及其方法詳細(xì)介紹
正則表達(dá)式是一種強(qiáng)大的文本處理工具,主要用于在字符串中進(jìn)行模式匹配、數(shù)據(jù)驗(yàn)證和文本替換,這篇文章主要給大家介紹了關(guān)于JavaScript正則表達(dá)式及其方法的詳細(xì)介紹,需要的朋友可以參考下2025-05-05
js 將線(xiàn)性數(shù)據(jù)轉(zhuǎn)為樹(shù)形的示例代碼
這篇文章主要介紹了js 將線(xiàn)性數(shù)據(jù)轉(zhuǎn)為樹(shù)形的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
JS運(yùn)動(dòng)特效之完美運(yùn)動(dòng)框架實(shí)例分析
這篇文章主要介紹了JS運(yùn)動(dòng)特效之完美運(yùn)動(dòng)框架,結(jié)合實(shí)例形式分析了javascript針對(duì)運(yùn)動(dòng)中的元素屬性檢測(cè)與判斷相關(guān)操作技巧,需要的朋友可以參考下2018-01-01

