停止使用 `let` 或?yàn)槭裁此?JavaScript/TypeScript 中是不必要的
你可能已經(jīng)遇到 let 關(guān)鍵字上百萬(wàn)次了。它是 JavaScript(以及擴(kuò)展的 TypeScript)中那些最初看起來(lái)像是救星的特性之一。
終于有了一種聲明變量的方式,可以尊重塊級(jí)作用域!var 造成提升和產(chǎn)生反直覺 bug 的日子一去不復(fù)返了。
但是重點(diǎn)來(lái)了:在 2024 年,使用 let 可能是你在代碼中做的最不必要的事情之一。
沒(méi)錯(cuò),你沒(méi)聽錯(cuò)。是時(shí)候停止使用 let 了。
讓我來(lái)解釋一下為什么,什么時(shí)候應(yīng)該用 const 替換它,以及在那些罕見的情況下,let 仍然在你的 TypeScript 文件中有一席之地。
let 的興衰 ??
我們回顧一下。在 ES6 之前的日子里,我們只能用 var。它是可以用的,但有深刻的缺陷。var 不尊重塊級(jí)作用域,這意味著如果你在 for 循環(huán)內(nèi)聲明了一個(gè) var,這個(gè)變量在循環(huán)外仍然可以訪問(wèn)。
這引發(fā)了混亂和充滿 bug 的代碼。ES6(也就是 ECMAScript 2015)通過(guò)引入 let 和 const 改變了游戲規(guī)則。突然間,我們有了塊級(jí)作用域的變量!
不再有 var 的噩夢(mèng)了!let 立即成為熱門,因?yàn)樗鉀Q了我們多年來(lái)一直在與之搏斗的問(wèn)題。
但是這里有一個(gè)問(wèn)題—const 是同時(shí)引入的,在大多數(shù)情況下,它可以說(shuō)是更優(yōu)的選擇。
為什么 const 應(yīng)該是你的默認(rèn)選擇 ??
我們面對(duì)現(xiàn)實(shí):不可變性是王道。在我們?nèi)粘>幊讨?,我們努力編寫可預(yù)測(cè)、易于理解且沒(méi)有副作用的代碼。
這就是 const 的用武之地。當(dāng)你使用 const 時(shí),你是在告訴自己和他人這個(gè)值不會(huì)改變。
這是一個(gè)保證—一個(gè)承諾,表示這個(gè)變量不會(huì)突然在你的代碼中途取得新值。
const PI = 3.14159;
const MAX_USERS = 100;
const CONFIG = { api: 'https://api.example.com', timeout: 5000 };
這使你的代碼更易讀和維護(hù)。你可以瞥一眼用 const 聲明的變量,立即知道它的意圖:這個(gè)值是固定的。
另一方面,let 引入了不確定性。當(dāng)你看到用 let 聲明的變量時(shí),你不能確定它是否會(huì)在后面發(fā)生變化。你必須在心理上或通過(guò)工具來(lái)跟蹤它,這增加了認(rèn)知負(fù)擔(dān)。
根據(jù)我的經(jīng)驗(yàn),在審查代碼時(shí),我經(jīng)??吹接?let 聲明的變量很容易就可以是 const。似乎開發(fā)者出于習(xí)慣默認(rèn)使用 let,即使他們不打算改變變量。
let 的問(wèn)題 ??
let 的主要問(wèn)題是它為不必要的可變性打開了大門。聲明某些東西時(shí)使用 let 太容易了,以至于后來(lái)忘記了為什么它一開始需要是可變的。
這里有一個(gè)快速示例:
let userCount = users.length;
if (someCondition) {
userCount += 1;
}
console.log(`Total users: ${userCount}`);
在這個(gè)例子中,使用 let 可能看起來(lái)無(wú)害,但問(wèn)問(wèn)自己—userCount 真的需要是可變的嗎?
如果我們使用 const 并重構(gòu)邏輯,代碼是否同樣清晰和功能性?
const userCount = users.length + (someCondition ? 1 : 0);
console.log(`Total users: ${userCount}`);
砰!更清晰的代碼,更少的可變性,更容易理解。
什么時(shí)候使用 let ??
那么,我們是否應(yīng)該完全拋棄 let?不完全是。let 確實(shí)有合法的使用場(chǎng)景,盡管它們比你想象的要少得多。
- 循環(huán)計(jì)數(shù)器:當(dāng)你需要迭代某些東西時(shí),let 通常是必要的。for 循環(huán)就是一個(gè)很好的例子:
for (let i = 0; i < 10; i++) {
console.log(i);
}
這里,i 需要在每次迭代中改變,所以 let 是正確的選擇。
- 可重新賦值的變量:如果你有一個(gè)真正需要改變其值的變量(而不僅僅是為了方便),那么 let 是合適的。
let status = 'pending';
// 一些異步操作
status = 'completed';
在這種情況下,重新賦值對(duì)邏輯至關(guān)重要。
但是這些場(chǎng)景比你預(yù)期的要少。通常,感覺需要 let 的地方可以重構(gòu)成 const,而不失去清晰度或功能性。
更好代碼的工具和技巧 ??
想要將你的代碼提升到下一個(gè)水平?這里有一些工具和技巧,可以幫助你最小化 let 的使用,擁抱 const 的力量:
- 代碼檢查工具:ESLint 是你的朋友。你可以配置 ESLint 在不必要使用 let 時(shí)發(fā)出警告或甚至拋出錯(cuò)誤。這會(huì)推動(dòng)你在使用 let 之前三思。
- 重構(gòu)工具:像 Prettier 或 VSCode 的內(nèi)置重構(gòu)工具可以幫助你快速將 let 轉(zhuǎn)換為 const(在適用的情況下)。只需右鍵點(diǎn)擊,看著魔法發(fā)生。
- 同行評(píng)審:鼓勵(lì)你的團(tuán)隊(duì)在代碼審查期間質(zhì)疑 let 的使用。問(wèn)問(wèn):"這真的需要是可變的嗎?"這將有助于在你的團(tuán)隊(duì)中灌輸不可變性的思維方式。
減少 let 聲明的高級(jí)方法 ??
如果你尋求另一種處理令人困惑的 let 聲明的方式,這個(gè)部分可能是你的救生衣。
?? 我看到的最常見的不必要 let 使用:設(shè)置初始值,然后進(jìn)行變異。
這很難閱讀,因?yàn)樗笞x者在閱讀時(shí)記住初始值,并監(jiān)控沿途的任何變異。
圖片
解決方案:改為調(diào)用一個(gè)函數(shù)。
圖片
不使用 let 并變異 formattedAddress 變量,你可以通過(guò)調(diào)用處理格式化的函數(shù)來(lái)提前返回。這消除了對(duì)可變性的需求,使你的代碼更清晰。
結(jié)論:擁抱不可變性
總結(jié)一下,在現(xiàn)代 JavaScript 和 TypeScript 中,let 應(yīng)該是例外而不是規(guī)則。通過(guò)默認(rèn)使用 const,你使你的代碼更可預(yù)測(cè)、更易讀、更不容易出錯(cuò)。當(dāng)然,有些情況下 let 是必要的,但那應(yīng)該是經(jīng)過(guò)深思熟慮的。
所以,下次當(dāng)你的手指懸停在鍵盤上,準(zhǔn)備輸入 let 時(shí),花點(diǎn)時(shí)間問(wèn)問(wèn)自己:"我真的需要這個(gè)是可變的嗎?"很可能,答案是否定的。