代碼水平暴增!掌握這五個(gè)JavaScript神技,讓你成為團(tuán)隊(duì)最靚的仔
每種現(xiàn)代編程語(yǔ)言通常有兩個(gè)主要部分:詞法語(yǔ)法和標(biāo)準(zhǔn)庫(kù)。編程語(yǔ)言語(yǔ)法通過保留關(guān)鍵字和特殊 ASCII 字符構(gòu)建了獨(dú)特的編程語(yǔ)法,供程序員編寫代碼。編程語(yǔ)言語(yǔ)法實(shí)現(xiàn)了一些語(yǔ)言特性,幫助開發(fā)者高效編寫自解釋的代碼以滿足各種開發(fā)需求。同時(shí),標(biāo)準(zhǔn)庫(kù)提供了訪問預(yù)先開發(fā)的通用編程功能(如字符串處理、數(shù)據(jù)結(jié)構(gòu)、日期/時(shí)間處理等)的接口。
JavaScript 具有一個(gè)預(yù)先導(dǎo)入的功能齊全的標(biāo)準(zhǔn)庫(kù),為開發(fā)者提供了各種預(yù)開發(fā)對(duì)象。例如,你可以使用標(biāo)準(zhǔn)的 ArrayBuffer 對(duì)象在 JavaScript 中處理原始二進(jìn)制數(shù)據(jù)。JavaScript 語(yǔ)法提供了基本的標(biāo)準(zhǔn)編程語(yǔ)法和現(xiàn)代、高效的 JavaScript 專用語(yǔ)言特性,幫助開發(fā)者更快、更干凈地編寫代碼。
在這篇文章中,我將討論一些只有少數(shù)開發(fā)者知道的隱藏的 JavaScript 詞法語(yǔ)法特性。實(shí)踐并使用這些高級(jí) JavaScript 語(yǔ)言特性,通過最大限度地利用 JavaScript 成為 JavaScript 專家!
標(biāo)記模板字面量函數(shù)
現(xiàn)如今,開發(fā)者使用 ES6 模板字面量進(jìn)行字符串插值,而不是舊式的字符串連接。模板字面量允許你通過在字符串段中嵌入表達(dá)式來構(gòu)建字符串,語(yǔ)法簡(jiǎn)潔易讀。JavaScript 模板字面量還支持使用標(biāo)記模板函數(shù)來解析帶有自定義邏輯的模板字符串。
標(biāo)記模板函數(shù)允許開發(fā)者訪問解析后的模板字符串的各個(gè)部分,因此你可以根據(jù)自定義解析需求輕松處理它。例如,以下 cap
標(biāo)記模板函數(shù)將每個(gè)表達(dá)式結(jié)果大寫:
function cap(strings, ...exps) {
return strings.reduce((acc, str, i) =>
(acc + str + (exps[i]?.toString()?.toUpperCase() ?? '')), '');
}
let str = cap`Hello ${'JavaScript'}... Hello ${'everyone'}...`;
console.log(str); // Hello JAVASCRIPT... Hello EVERYONE...
如上面的代碼片段所示,你可以使用傳遞給標(biāo)記函數(shù)的參數(shù)處理評(píng)估后的模板字符串。你甚至可以從標(biāo)記函數(shù)返回對(duì)象。因此,使用標(biāo)記函數(shù)進(jìn)行字符串到對(duì)象數(shù)據(jù)轉(zhuǎn)換是標(biāo)記模板字面量的一個(gè)很好的用例。以下 json 標(biāo)記函數(shù)實(shí)現(xiàn)了一種更好的語(yǔ)法方法來解析代碼中的 JSON 字符串:
function json(strings, ...exps) {
return JSON.parse(strings.reduce((acc, str, i) =>
(acc + str + (exps[i] ?? '')), ''));
}
let obj = json`{
"msg": "Hello JavaScript",
"code": ${1000}
}`;
console.log(obj); // {msg: 'Hello JavaScript', code: 1000}
類似地,你可以開發(fā)標(biāo)簽來轉(zhuǎn)換 YAML 和 HTML 格式:
let yamlObj = yaml`...`;
let htmlObj = html`...`;
流行的 Google 開源庫(kù) zx 讓你可以使用標(biāo)記模板字面量特性在 Node.js 中編寫類似 Bash 的腳本。
原生非十進(jìn)制數(shù)字字面量
人類通常使用十進(jìn)制數(shù)系統(tǒng),因此每種編程語(yǔ)言都將數(shù)字字面量視為十進(jìn)制數(shù)。但在某些開發(fā)場(chǎng)景中,我們必須在源代碼中使用其他數(shù)制。例如,我們應(yīng)該使用八進(jìn)制數(shù)來通過 Node.js API 更改文件系統(tǒng)訪問權(quán)限。任何現(xiàn)代編程語(yǔ)言,包括 JavaScript,使用一組通用前綴來表示非十進(jìn)制數(shù)字字面量。
看看如何使用標(biāo)準(zhǔn)前綴在 JavaScript 中使用二進(jìn)制、八進(jìn)制和十六進(jìn)制數(shù)字字面量:
let n1 = 0b101;
let n2 = 0o21;
let n3 = 0xff;
console.log(n1); // 5
console.log(n2); // 17
console.log(n3); // 255
如你所見,每個(gè)非十進(jìn)制數(shù)字立即轉(zhuǎn)換為十進(jìn)制數(shù)字,這意味著 JavaScript 在解析源文件時(shí)實(shí)現(xiàn)了這種非十進(jìn)制數(shù)字支持,并在運(yùn)行時(shí)使用通用的 Number 對(duì)象。
然而,內(nèi)置的 toString() 方法和 parseInt() 函數(shù)幫助開發(fā)者通過將非十進(jìn)制數(shù)字存儲(chǔ)為字符串來處理它們:
let n1 = '0xff';
let n2 = parseInt(n1, 16);
console.log(n2); // 255 (decimal)
let n3 = n2.toString(2);
console.log(n3); // 11111111 (binary)
使用字符串格式顯示二進(jìn)制數(shù)字并不是大問題,但在字符串中存儲(chǔ)大量二進(jìn)制數(shù)據(jù)不是性能友好的方法,因此你可以改用類型化數(shù)組。
使用對(duì)象方法防止 JavaScript 對(duì)象修改
默認(rèn)情況下,JavaScript 不會(huì)對(duì)對(duì)象進(jìn)行嚴(yán)格檢查——它允許你隨意操作任何對(duì)象。你甚至可以操作內(nèi)置對(duì)象:
JSON.parse = (str) => console.log(str);
例如,你可以通過在瀏覽器控制臺(tái)中覆蓋內(nèi)置對(duì)象方法來破壞生產(chǎn)網(wǎng)站(僅限當(dāng)前瀏覽器標(biāo)簽頁(yè)),如上面的代碼片段所示。
JavaScript 允許你使用 Object.seal() 和 Object.freeze() 方法防止對(duì)象修改。例如,seal() 方法通過允許現(xiàn)有屬性值修改來防止新屬性添加:
const obj = {
a: 100,
f: () => console.log('Hello...')
};
Object.seal(obj);
obj.a = 1000; // works
obj.b = 100; // doesn't work
delete obj.a; // doesn't work
Object.freeze() 防止添加新屬性并阻止現(xiàn)有屬性修改,如下代碼片段所示:
Object.freeze(obj);
obj.a = 1000; // doesn't work
obj.b = 100; // doesn't work
delete obj.a; // doesn't work
默認(rèn)情況下,密封和凍結(jié)對(duì)象不會(huì)因無效操作而拋出錯(cuò)誤,因此你必須啟用 JavaScript 嚴(yán)格模式才能實(shí)現(xiàn)這一點(diǎn)。
嵌套解構(gòu)和重命名
現(xiàn)如今,由于 React 等庫(kù)教程的影響,開發(fā)者經(jīng)常使用 ES6 解構(gòu)特性與對(duì)象和數(shù)組。解構(gòu)特性提供了一種更好的語(yǔ)法糖,用于通過從數(shù)組和對(duì)象中提取字段來創(chuàng)建新變量/常量?;緦?duì)象解構(gòu)通常從第一級(jí)屬性提取屬性,如下所示:
const obj = {
a: 10,
b: 20,
c: 30
};
let {a, b, c} = obj;
console.log(a, b, c); // 10 20 30
如果你需要重命名變量名,可以使用解構(gòu)重命名語(yǔ)法,如下所示:
let {a: A, b: B, c: C} = obj;
console.log(A, B, C); // 10 20 30
我們看看一個(gè)高級(jí)對(duì)象解構(gòu)示例。我們可以從嵌套屬性中提取數(shù)據(jù)并使用重命名語(yǔ)法,如下代碼片段所示
const customer = {
info: {
name: 'John',
score: 80,
address: {postalCode: 2000}
}
};
let {
info: {
name: customerName,
address: {postalCode: postCode }
}
} = customer;
console.log(customerName, postCode); // John 2000
在這里,我們通過結(jié)合解構(gòu)和重命名特性提取嵌套屬性,創(chuàng)建了兩個(gè)變量。你甚至可以使用剩余參數(shù)語(yǔ)法獲取解構(gòu)過程中未解包的對(duì)象屬性:
let {
info: {
name: customerName,
address: { postalCode: postCode },
...rest
}
} = customer;
上面的 ...rest 對(duì)象包含 { score: 80 } 對(duì)象,因?yàn)?score 屬性未被解包到單獨(dú)的變量中。
使用計(jì)算屬性創(chuàng)建鍵值對(duì)象
在某些開發(fā)場(chǎng)景中,我們需要?jiǎng)討B(tài)訪問對(duì)象屬性。我們可以輕松地使用括號(hào)語(yǔ)法動(dòng)態(tài)設(shè)置/獲取屬性,但使用多個(gè)重復(fù)的設(shè)置/獲取語(yǔ)句無疑會(huì)影響代碼可讀性。
看看以下代碼片段,使用括號(hào)語(yǔ)法設(shè)置動(dòng)態(tài)屬性名:
function createElement(tag, score) {
let doc = {
id: 100,
tag,
};
doc[tag + 'Score'] = score * 100;
doc[tag + 'Type'] = 'internal';
return doc;
}
console.log(createElement('box', 50));
// {id: 100, boxScore: 5000, boxType: 'internal'}
我們可以使用計(jì)算屬性語(yǔ)法簡(jiǎn)化上述函數(shù),如下所示:
const createElement = (tag, score) => ({
id: 100,
tag,
[tag + 'Score']: score * 100,
[tag + 'Type']: 'internal'
});
現(xiàn)代 JavaScript 語(yǔ)法是如此富有成效--它甚至支持對(duì)象重構(gòu)語(yǔ)法中的計(jì)算屬性,因此您可以使用動(dòng)態(tài)生成的屬性名來解包屬性。例如,下面的代碼片段使用對(duì)象重構(gòu)和計(jì)算屬性語(yǔ)法,找到了使用上述 createElement() 函數(shù)生成的特定對(duì)象的分?jǐn)?shù)字段:
let obj = {
id: 100,
tag: 'box',
boxScore: 5000,
boxType: 'internal'
};
let {[obj.tag + 'Score']: score} = obj;
console.log(score); // 5000
總結(jié)
這篇文章探討了一些鮮為人知的 JavaScript 語(yǔ)言特性,這些特性可以幫助你通過編寫簡(jiǎn)潔的代碼塊來提高編碼效率。除了這些特性之外,指數(shù)運(yùn)算符、類似逗號(hào)運(yùn)算符的語(yǔ)法增強(qiáng)功能也可以幫助你以專家的方式編寫 JavaScript 代碼,并保持最新的知識(shí)!
ECMAScript 通過討論社區(qū)提案積極改進(jìn)標(biāo)準(zhǔn)的 JavaScript 規(guī)范。ECMAScript TC39 小組維護(hù)了一個(gè) GitHub 倉(cāng)庫(kù),列出了最新的 JavaScript 增強(qiáng)提案。其中一些提案試圖擴(kuò)展 JavaScript 語(yǔ)法以提高開發(fā)者的生產(chǎn)力。例如,一些提案嘗試標(biāo)準(zhǔn)化 function.sent 元屬性、為 throw 關(guān)鍵字支持表達(dá)式以及類似函數(shù)管道的語(yǔ)言修改,適用于所有流行的網(wǎng)頁(yè)瀏覽器。