11個(gè)ES13中令人驚嘆的JavaScript新特性總結(jié)
前言
與許多其他編程語言一樣,JavaScript 也在不斷發(fā)展。每年,該語言都會(huì)通過新功能變得更加強(qiáng)大,使開發(fā)人員能夠編寫更具表現(xiàn)力和簡(jiǎn)潔的代碼。 小編今天就為大家介紹ES13中添加的最新功能,并查看其用法示例以更好地理解它們。
1.類
在ES13之前,類字段只能在構(gòu)造函數(shù)中聲明。與許多其他語言不同,無法在類的最外層作用域中聲明或定義它們。
class Car { constructor() { this.color = 'blue'; this.age = 2; } } const car = new Car(); console.log(car.color); // blue console.log(car.age); //
而ES13 消除了這個(gè)限制。現(xiàn)在我們可以編寫這樣的代碼:
class Car { color = 'blue'; age = 2; }const car = new Car(); console.log(car.color); // blue console.log(car.age); // 2
2.私有方法和字段
ES13以前,不可能在類中聲明私有成員。成員傳統(tǒng)上帶有下劃線 ( _) 前綴,以表明它是私有的,但仍然可以從類外部訪問和修改它。
class Person { _firstName = 'Joseph'; _lastName = 'Stevens'; get name() { return `${this._firstName} ${this._lastName}`; } }const person = new Person(); console.log(person.name); // Joseph Stevens // 仍可以從類外部訪問 // 原本打算設(shè)為私有的成員 console.log(person._firstName); // Joseph console.log(person._lastName); // Stevens // 也可以修改 person._firstName = 'Robert'; person._lastName = 'Becker';console.log(person.name); // Robert Becker
使用 ES13,我們現(xiàn)在可以通過在類前面添加 ( #) 來向類添加私有字段和成員。嘗試從外部訪問這些類將會(huì)引發(fā)錯(cuò)誤:
class Person { #firstName = 'Joseph'; #lastName = 'Stevens'; get name() { return `${this.#firstName} ${this.#lastName}`; } }const person = new Person(); console.log(person.name); // 語法錯(cuò)誤:私有字段 '#firstName' 必須在一個(gè)外層類中聲明 console.log(person.#firstName); console.log(person.#lastName);
3.await頂層操作
在 JavaScript 中,await運(yùn)算符用于暫停執(zhí)行,直到 一個(gè)Promise被解決(執(zhí)行或拒絕)。 以前只能在async中使用此運(yùn)算符。不可以在全局作用域中直接使用await。
function setTimeoutAsync(timeout) { return new Promise((resolve) => { setTimeout(() => { resolve(); }, timeout); }); } //語法錯(cuò)誤:await 僅在異步函數(shù)中有效 await setTimeoutAsync(3000);
有了 ES13,現(xiàn)在我們可以:
function setTimeoutAsync(timeout) { return new Promise((resolve) => { setTimeout(() => { resolve(); }, timeout); }); } // 等待超時(shí) - 沒有錯(cuò)誤拋出 await setTimeoutAsync(3000);
4.靜態(tài)類字段和靜態(tài)私有方法
現(xiàn)在可以在 ES13 中為類聲明靜態(tài)字段和靜態(tài)私有方法。靜態(tài)方法可以使用關(guān)鍵字this訪問類中的其他私有/公共靜態(tài)成員,實(shí)例方法可以使用this.constructor訪問他們。
class Person { static #count = 0; static getCount() { return this.#count; } constructor() { this.constructor.#incrementCount(); } static #incrementCount() { this.#count++; } }const person1 = new Person(); const person2 = new Person();console.log(Person.getCount()); // 2
5.類靜態(tài)塊
ES13 引入了一項(xiàng)特性,允許開發(fā)者定義僅在創(chuàng)建類時(shí)執(zhí)行一次的靜態(tài)塊。這一特性與其他面向?qū)ο缶幊陶Z言(如 C# 和 Java)中的靜態(tài)構(gòu)造函數(shù)相似。
在一個(gè)類的主體中,你可以定義任意數(shù)量的靜態(tài) {} 初始化塊。它們會(huì)按照聲明的順序與任何交錯(cuò)的靜態(tài)字段初始值設(shè)定項(xiàng)一起執(zhí)行。此外,你還可以通過塊中的 super 關(guān)鍵字訪問超類的靜態(tài)屬性。這為開發(fā)者提供了更多的靈活性和控制能力。
class Vehicle { static defaultColor = 'blue'; }class Car extends Vehicle { static colors = []; static { this.colors.push(super.defaultColor, 'red'); } static { this.colors.push('green'); } }console.log(Car.colors); // [ 'blue', 'red', 'green' ]
6.檢查對(duì)象中的私有字段
開發(fā)者如今可以利用這一新功能,使用運(yùn)算符in來方便地檢查對(duì)象是否包含某個(gè)特定的私有字段。
class Car { #color; hasColor() { return #color in this; } }const car = new Car(); console.log(car.hasColor()); // true;
通過運(yùn)算符in,可以準(zhǔn)確區(qū)分不同類中具有相同名稱的私有字段。
class Car { #color; hasColor() { return #color in this; } }class House { #color; hasColor() { return #color in this; } }const car = new Car(); const house = new House();console.log(car.hasColor()); // true; console.log(car.hasColor.call(house)); // false console.log(house.hasColor()); // true console.log(house.hasColor.call(car)); // false
7.at() 索引方法
在 JavaScript 中,我們通常使用方括號(hào)[]來訪問數(shù)組的第 t 個(gè)元素。這個(gè)過程非常簡(jiǎn)單,但實(shí)際上我們只是訪問了索引為 t-1 的數(shù)組屬性而已。
const arr = ['a', 'b', 'c', 'd']; console.log(arr[1]); // b
然而,當(dāng)我們希望通過方括號(hào)來訪問數(shù)組末尾的第 N 個(gè)元素時(shí),我們需要使用索引 arr.length - N。
const arr = ['a', 'b', 'c', 'd']; // 從末尾開始第一個(gè)元素 console.log(arr[arr.length - 1]); // d // 倒數(shù)第二個(gè)元素 console.log console.log(arr[arr.length - 2]); // c
借助全新的at()方法,可以以更加精簡(jiǎn)和富有表現(xiàn)力的方式來實(shí)現(xiàn)這一目標(biāo)。要訪問數(shù)組末尾的第N個(gè)元素,只需將負(fù)值-N作為參數(shù)傳遞給at()方法即可。
const arr = ['a', 'b', 'c', 'd']; // 從末尾開始第一個(gè)元素 console.log(arr.at(-1)); // d // 倒數(shù)第二個(gè)元素 console.log console.log(arr.at(-2)); // c
除了數(shù)組之外,字符串和TypedArray對(duì)象現(xiàn)在也有at()方法。
const str = 'Coding Beauty'; console.log(str.at(-1)); // y console.log(str.at(-2)); // tconst typedArray = new Uint8Array([16, 32, 48, 64]); console.log(typedArray.at(-1)); // 64 console.log(typedArray.at(-2)); // 48
8.正則表達(dá)式匹配索引
在ES13之前,我們只能獲取字符串中正則表達(dá)式匹配的起始索引,
const str = 'sun and moon';const regex = /and/;const matchObj = regex.exec(str);// [ 'and', index: 4, input: 'sun and moon', groups: undefined ] console.log(matchObj);
使用ES13之后,可以通過指定一個(gè)/d正則表達(dá)式標(biāo)志來獲取匹配開始和結(jié)束的兩個(gè)索引。這一特性賦予了更多的靈活性和控制能力。
const str = 'sun and moon'; const regex = /and/d; const matchObj = regex.exec(str); /** [ 'and', index: 4, input: 'sun and moon', groups: undefined, indices: [ [ 4, 7 ], groups: undefined ] ] */ console.log(matchObj);
設(shè)置標(biāo)志后d,返回的對(duì)象將具有indices包含起始索引和結(jié)束索引的屬性。
9.Object.hasOwn()方法
在 JavaScript 中,我們可以使用Object.prototype.hasOwnProperty()方法來檢查對(duì)象是否具有給定的屬性。
class Car { color = 'green'; age = 2; }const car = new Car();console.log(car.hasOwnProperty('age')); // true console.log(car.hasOwnProperty('name')); // false
然而,這種方法存在一些問題。首先,Object.prototype.hasOwnProperty()方法并未受到保護(hù),這意味著我們可以通過自定義的hasOwnProperty()方法來覆蓋它,而這個(gè)自定義方法可能會(huì)具有與Object.prototype.hasOwnProperty()不同的行為。需要額外注意的是這一點(diǎn)。
class Car { color = 'green'; age = 2; // This method does not tell us whether an object of // this class has a given property. hasOwnProperty() { return false; } }const car = new Car();console.log(car.hasOwnProperty('age')); // false console.log(car.hasOwnProperty('name')); // false
另外一個(gè)問題是,如果我們使用了 null 原型(通過 Object.create(null) 創(chuàng)建的對(duì)象),那么試圖調(diào)用該方法將會(huì)產(chǎn)生錯(cuò)誤。
const obj = Object.create(null); obj.color = 'green'; obj.age = 2; // TypeError: obj.hasOwnProperty 不是函數(shù) console.log(obj.hasOwnProperty('color'));
為了克服這些問題,我們可以利用屬性調(diào)用方法Object.prototype.hasOwnProperty.call()來解決。具體示例如下所示:
const obj = Object.create(null); obj.color = 'green'; obj.age = 2; obj.hasOwnProperty = () => false;console.log(Object.prototype.hasOwnProperty.call(obj, 'color')); // true console.log(Object.prototype.hasOwnProperty.call(obj, 'name')); // false
這種方式并不十分便利。為了避免重復(fù),我們可以編寫一個(gè)可重用的函數(shù),這樣可以使我們的代碼更加簡(jiǎn)潔和高效:
function objHasOwnProp(obj, propertyKey) { return Object.prototype.hasOwnProperty.call(obj, propertyKey); }const obj = Object.create(null); obj.color = 'green'; obj.age = 2; obj.hasOwnProperty = () => false;console.log(objHasOwnProp(obj, 'color')); // true console.log(objHasOwnProp(obj, 'name')); // false
現(xiàn)在不需要在那樣做了,我們還可以使用全新的內(nèi)置方法Object.hasOwn()來處理這個(gè)問題。它與我們之前編寫的可重用函數(shù)類似,接受對(duì)象和屬性作為參數(shù),并且返回一個(gè)布爾值,如果指定的屬性是對(duì)象的直接屬性,則返回true;否則返回false。
const obj = Object.create(null); obj.color = 'green'; obj.age = 2; obj.hasOwnProperty = () => false;console.log(Object.hasOwn(obj, 'color')); // true console.log(Object.hasOwn(obj, 'name')); // false
10.錯(cuò)誤原因?qū)傩?/h2>
現(xiàn)在,錯(cuò)誤對(duì)象已經(jīng)增加了一個(gè)cause屬性,該屬性用于指定導(dǎo)致錯(cuò)誤拋出的原始錯(cuò)誤。通過這種方式,我們可以為錯(cuò)誤添加額外的上下文信息,從而更好地診斷意外的行為。要指定錯(cuò)誤的原因,我們可以在作為構(gòu)造函數(shù)的第二個(gè)參數(shù)傳遞給Error()的對(duì)象中設(shè)置屬性來實(shí)現(xiàn)。這種方法能夠提供更豐富的錯(cuò)誤追蹤和調(diào)試信息。
function userAction() { try { apiCallThatCanThrow(); } catch (err) { throw new Error('New error message', { cause: err }); } }try { userAction(); } catch (err) { console.log(err); console.log(`Cause by: ${err.cause}`); }
11.從數(shù)組最后查找
在 JavaScript 中,我們已經(jīng)可以使用Array的find()方法來查找數(shù)組中滿足指定測(cè)試條件的元素。類似地,我們也可以使用findIndex()方法來獲取滿足條件的元素的索引值。盡管find()和findIndex()都是從數(shù)組的第一個(gè)元素開始搜索,但在某些情況下,從最后一個(gè)元素開始搜索可能會(huì)更有效。
有些情況下,我們知道從數(shù)組的末尾進(jìn)行查找可能會(huì)獲得更好的性能表現(xiàn)。例如,在這里我們嘗試查找數(shù)組中prop屬性等于"value"的項(xiàng)目。這時(shí)候,可以通過使用reverse()方法將數(shù)組反轉(zhuǎn),然后使用find()和findIndex()方法來從末尾開始搜索。下面是具體的實(shí)現(xiàn)示例:
const letters = [ { value: 'v' }, { value: 'w' }, { value: 'x' }, { value: 'y' }, { value: 'z' }, ];const found = letters.find((item) => item.value === 'y'); const foundIndex = letters.findIndex((item) => item.value === 'y');console.log(found); // { value: 'y' } console.log(foundIndex); // 3
上面的代碼可以獲取正確結(jié)果,但由于目標(biāo)對(duì)象更接近數(shù)組的尾部,如果我們使用findLast()和findLastIndex()方法來從數(shù)組的末尾進(jìn)行搜索,很可能能夠顯著提升程序的執(zhí)行效率。通過這種方式,我們可以更快地找到所需的元素或索引,從而優(yōu)化代碼性能。
const letters = [ { value: 'v' }, { value: 'w' }, { value: 'x' }, { value: 'y' }, { value: 'z' }, ];const found = letters.findLast((item) => item.value === 'y'); const foundIndex = letters.findLastIndex((item) => item.value === 'y');console.log(found); // { value: 'y' } console.log(foundIndex); // 3
在一些特定的使用場(chǎng)景中,我們可能需要從數(shù)組的末尾開始搜索來獲取準(zhǔn)確的元素。舉個(gè)例子,假設(shè)我們要查找數(shù)字列表中的最后一個(gè)偶數(shù),使用find()或findIndex()方法可能會(huì)導(dǎo)致錯(cuò)誤的結(jié)果:
const nums = [7, 14, 3, 8, 10, 9]; // 給出 14,而不是 10 const lastEven = nums.find((value) => value % 2 === 0); // 給出 1,而不是 4 const lastEvenIndex = nums.findIndex((value) => value % 2 === 0);console.log(lastEven); // 14 console.log(lastEvenIndex); // 1
如果我們?cè)谡{(diào)用reverse()方法之前使用數(shù)組的slice()方法創(chuàng)建新的數(shù)組副本,就可以避免不必要地改變?cè)紨?shù)組的順序。然而,在處理大型數(shù)組時(shí),這種方法可能會(huì)導(dǎo)致性能問題,因?yàn)樾枰獜?fù)制整個(gè)數(shù)組。
此外,findIndex()方法在反轉(zhuǎn)數(shù)組時(shí)仍然無法達(dá)到預(yù)期效果,因?yàn)樵氐姆崔D(zhuǎn)會(huì)導(dǎo)致它們?cè)谠紨?shù)組中的索引改變。為了獲取元素的原始索引,我們需要進(jìn)行額外的計(jì)算,這意味著需要編寫更多的代碼來處理這種情況。
const nums = [7, 14, 3, 8, 10, 9]; // 在調(diào)用reverse()之前使用展開語法復(fù)制整個(gè)數(shù)組 // calling reverse() const reversed = [...nums].reverse(); // 正確給出 10 const lastEven = reversed.find((value) => value % 2 === 0); // 給出 1,而不是 4 const reversedIndex = reversed.findIndex((value) => value % 2 === 0); // 需要重新計(jì)算得到原始索引 const lastEvenIndex = reversed.length - 1 - reversedIndex;console.log(lastEven); // 10 console.log(reversedIndex); // 1 console.log(lastEvenIndex); // 4
使用findLast()和findLastIndex()方法在需要查找數(shù)組中最后一個(gè)符合條件的元素或索引時(shí)非常實(shí)用。它們能夠準(zhǔn)確地定位目標(biāo)對(duì)象,并且從數(shù)組末尾開始搜索,提供了高效的解決方案。
const nums = [7, 14, 3, 8, 10, 9];const lastEven = nums.findLast((num) => num % 2 === 0); const lastEvenIndex = nums.findLastIndex((num) => num % 2 === 0);console.log(lastEven); // 10 console.log(lastEvenIndex); // 4
結(jié)論
ES13 為 JavaScript 帶來了一系列令人振奮的新功能,我們已經(jīng)有幸見識(shí)了它們的魅力。通過運(yùn)用這些功能,開發(fā)人員的工作效率將得到極大提升,同時(shí)也能以更加簡(jiǎn)潔、明晰的方式書寫出更加純凈、精煉的代碼。這些新特性為我們帶來了更大的靈活性和便利性,使得我們的開發(fā)過程更加高效、愉悅。
以上就是11個(gè)ES13中令人驚嘆的JavaScript新特性總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript ES13的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
js使用DOM操作實(shí)現(xiàn)簡(jiǎn)單留言板的方法
這篇文章主要介紹了js使用DOM操作實(shí)現(xiàn)簡(jiǎn)單留言板的方法,涉及javascript中DOM操作的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04javascript制作坦克大戰(zhàn)全紀(jì)錄(1)
本文寫作的目的是鞏固一下自己最近學(xué)習(xí)的js知識(shí), 這個(gè)教程適合熟悉js基本語法和面向?qū)ο笳Z法的小伙伴學(xué)習(xí)。由于自己也是剛學(xué)js不久,所以難免出現(xiàn)錯(cuò)誤。如果發(fā)現(xiàn)希望給予指正。2014-11-11下拉菜單點(diǎn)擊實(shí)現(xiàn)連接跳轉(zhuǎn)功能的js代碼
下拉菜單點(diǎn)擊實(shí)現(xiàn)連接跳轉(zhuǎn)效果想必不是很常見吧,下面與大家分享下具體的實(shí)現(xiàn)另有實(shí)例,感興趣的朋友可以參考下哈2013-05-05用JS實(shí)現(xiàn)HTML標(biāo)簽替換效果
用JS實(shí)現(xiàn)HTML標(biāo)簽替換效果...2007-06-06javascript顯示動(dòng)態(tài)時(shí)間的方法匯總
本文給大家匯總介紹了3種javascript實(shí)現(xiàn)動(dòng)態(tài)顯示時(shí)間的方法及詳細(xì)示例,有需要的小伙伴可以參考下2018-07-07javascript中apply和call方法的作用及區(qū)別說明
本篇文章主要是對(duì)javascript中apply和call方法的作用及區(qū)別進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-02-02微信小程序?qū)崙?zhàn)篇之購物車的實(shí)現(xiàn)代碼示例
本篇文章主要介紹了微信小程序?qū)崙?zhàn)篇之購物車的實(shí)現(xiàn)代碼示例,詳細(xì)的介紹了購物車的功能實(shí)現(xiàn),具有一定的參考價(jià)值,有興趣的可以了解一下2017-11-11