ECMAScript 2023(ES14)中的所有新功能

JavaScript在持續(xù)發(fā)展,近期ECMAScript 14中發(fā)布添加了一批新功能,讓我們一起來探索一下今年對JavaScript開發(fā)人員的新功能。時間的車輪又過去了一年,隨之而來的是JavaScript的新官方版本:ECMAScript 2023,也被稱為ECMAScript 14。今年的改進包括對數(shù)組的添加和對ECMAScript文件中shebang的支持,以及對弱集合的符號鍵的擴展。這些變化主要是對語言的細化改進,而不是什么重大的變革。然而,這些改變的綜合效果是繼續(xù)推進語言的發(fā)展。下面是JavaScript在2023年的新功能概覽演示。

理解規(guī)范

ECMAScript規(guī)范是一份令人印象深刻的文檔,既是開發(fā)人員和教育者的基本參考,也是JavaScript引擎實現(xiàn)者的官方技術(shù)規(guī)范。這是一個相當(dāng)平衡的過程,規(guī)范處理得很好。由于包含了大量的信息,它作為語言的用戶指南可能有些繁瑣。

關(guān)于規(guī)范的另一個要了解的事情是,它實際上是一個活動的文檔,在語言在實際應(yīng)用中使用時會不斷發(fā)展。通常情況下,新功能在被用戶社區(qū)非正式接受后才會被添加到官方規(guī)范中。例如,今年的shebang語法就是一個例子。一旦一個功能被規(guī)范所編碼和標(biāo)準(zhǔn)化,規(guī)范就成為進一步創(chuàng)新該功能的新穩(wěn)定基礎(chǔ)。

有時,ECMAScript規(guī)范引入了開創(chuàng)性的想法。一個例子是采用了受C#影響的/語法。async/await 作為一種語言,JavaScript已經(jīng)從復(fù)制粘貼的鼠標(biāo)懸停效果的時代飛躍而來。ECMAScript規(guī)范過程在這一演變中起到了巨大的作用。

現(xiàn)在,讓我們來看看在2023年引入的JavaScript的新功能。

數(shù)組原型對象的toSorted方法

讓我們從新的數(shù)組方法toSorted()開始。toSorted()具有與sort()相同的簽名,但它創(chuàng)建一個新的數(shù)組,而不是在原數(shù)組上進行操作。下面是列表1中的新數(shù)組方法Array.prototype.sort()與toSorted()的對比。

列表1. sort()與toSorted()的對比

let arr = [5,4,2,3,1]
arr === arr.sort(); // true - [1, 2, 3, 4, 5]

arr === arr.toSorted(); // false - [1, 2, 3, 4, 5]

toSorted()和sort()一樣,也接受一個可選的參數(shù),即比較函數(shù)。例如,我們可以使用toSorted()創(chuàng)建一個按降序排列的新數(shù)組,如列表2所示。

列表2. 使用比較函數(shù)

const numbers = [10, 5, 2, 7, 3, 9, 1, 6, 4]; 
const sortedNumbers = numbers.toSorted((a, b) => { 
  return b - a; 
}); 
console.log(sortedNumbers); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

還需要注意的是,toSorted()也可以應(yīng)用于對象數(shù)組。在這種情況下,您必須提供一個使用對象上的數(shù)據(jù)的比較函數(shù),因為對象沒有自然的排序方式。您可以在列表3中看到一個示例。

列表3. 使用對象的toSorted()

// Comparing objects
const objects = [{ name: "John", age: 30 }, { name: "Jane", age: 25 }, { name: "Bill", age: 40 }, { name: "Mary", age: 20 }];
const sortedObjects = objects.toSorted((a, b) => {
  return a.name.localeCompare(b.name); 
});
console.log(sortedObjects);
//[{"name":"Bill","age":40},{"name":"Jane","age":25},{"name":"John","age":30},{"name":"Mary","age":20}]

與toSorted()和sort()類似,toReversed()是reverse()的復(fù)制版本。列表4中有一些使用toReversed()的快速示例,包括將其應(yīng)用于帶有比較函數(shù)的對象。

列表4. 使用toReversed()

["a","b","c","d","e"].toReversed(); // ['e', 'd', 'c', 'b', 'a']

Array.prototype.with新的with()方法允許您根據(jù)索引修改單個元素,并返回一個新的數(shù)組。因此,如果您知道索引和新值,這個方法非常方便。請注意,with()是set()的復(fù)制伴侶。列表5給出了一個簡單的示例。

列表5. 使用with()和set()方法的示例

const arr4 = ["I", "am", "the", "Walrus"];

// Replace the string "Walrus" with "Octopus".
const newArr4 = arr4.with(3, "Ape Man");

console.log(newArr4);

Array.prototype.findLast方法允許您從數(shù)組中獲取最后一個匹配元素的實例。如果沒有找到匹配的元素,則返回undefined。在列表6中給出了一個簡單的示例,我們從數(shù)組中獲取最后一個偶數(shù)。

列表6. 使用findLast()方法的示例

onst arr = [54, 34, 55, 75, 98, 77];

const lastEvenIndex = arr.findLast((element) => {
  return element % 2 === 0;
});

console.log(lastEvenIndex); // 98

findLast()還支持傳入一個" "來設(shè)置上下文。也就是說,第二個參數(shù)將告訴第一個參數(shù)函數(shù)關(guān)鍵字將指向什么。您可以在列表7中看到這一點,在列表7中,我們使用一個自定義對象來查找第一個可以被5.thisArgthis整除的元素。

列表7.使用thisArg

const arr6 = [54, 34, 55, 75, 98, 77];
const myObject = {testCase: 5};
const lastEvenIndex = arr5.findLast((element) => {
  return element % myObject.testCase === 0;
}, myObject);

console.log(lastEvenIndex); // 75

findLastIndex()的工作方式與之完全相同,只不過它提供的是元素匹配的索引,而不是元素本身。例如,列表8顯示了如何查找可被6整除的最后一個元素的索引。

列表8.使用findLastIndex()查找元素的索引

const arr = [54, 34, 55, 75, 98, 77];
arr.findLastIndex(x => x % 6 === 0); // 0

Array.prototype.toSpliced到目前為止,我們描述的所有方法也適用于。最后一個新的數(shù)組方法toSpliced()只存在于。該方法是JavaScript數(shù)組操作的復(fù)制版本——這是一種熟悉的瑞士軍刀。拼接TypedArrayArraytoSpliced () ()假設(shè)我們有一個顏色數(shù)組,我們需要在中間插入兩個新顏色(粉色和青色)??梢栽谇鍐?中看到這一點。記住,這會創(chuàng)建一個新數(shù)組,而不是修改原來的數(shù)組。

列表9.操作中的toSpliced()

const arr = ["red", "orange", "yellow", "green", "blue", "purple"]; const newArr = arr.toSpliced(2, 1, "pink", "cyan"); console.log(newArr); 
// ["red", "orange", "pink", "cyan", "green", "blue", "purple"]
console.log(newArr[3]);
// 'cyan'
console.log(arr[3]);
// ‘green’

shebang是一種老式的Unix說法,表示一個標(biāo)簽后面跟著一個感嘆號(其中“bang”是“!”的俚語)。自古以來,在文件開頭的注釋就會告訴shell這里是一個可執(zhí)行腳本,以及使用什么引擎來運行它。

列表10.一個典型的bash腳本

#!/bin/bash

echo "Hello, world!"

你可以像列表10中的示例那樣直接運行一個文件,使用../hello.sh命令。在JavaScript中,你也可以做類似的操作,如列表11所示。

列表11. JavaScript中的Shebang: hello.js

#!/usr/bin/env node

console.log("Hello, world!");

列表11中的代碼告訴操作系統(tǒng)使用node程序來運行這個腳本?,F(xiàn)在,你可以直接輸入命令來運行它。如果沒有Shebang注釋,../hello.js這樣是行不通的。Shebang支持是規(guī)范中的一個功能更新,已經(jīng)在多個上下文中非官方地采用和實現(xiàn)。ECMAScript 14中的最后一個新功能是擴展了可以用作弱引用集合鍵的內(nèi)容。與日常JavaScript用法相比,弱引用集合有點晦澀。在編程中,弱引用是指如果它本來應(yīng)該被垃圾回收,那么它將被丟棄。換句話說,單獨的弱引用不足以阻止垃圾回收算法將引用目標(biāo)丟棄(這就是為什么它是弱引用)。你可以在這里了解更多關(guān)于弱引用以及它們何時有用的信息。這里也有一個很好的討論。 ES14允許在集合中使用大多數(shù)符號作為鍵,而以前只能使用對象。如果你想知道什么是符號,你并不孤單。你可以在這里了解更多關(guān)于符號的信息。這個新功能本質(zhì)上使得在集合中使用弱引用更加容易,通過放寬可以用作鍵的限制。列表12中展示了一個簡單的示例。

列表12. 在WeakMap中使用符號作為鍵

var map = new WeakMap(); // create a weak map
function useSymbol(symbol){
    doSomethingWith(symbol);
    var called = map.get(symbol) || 0;
    called++; // called one more time
    if(called > 2) console.log(“Called more than twice”);
    map.set(symbol, called);
}

let mySymbol = Symbol(“FooBar”);
useSymbol(mySymbol);
useSymbol(mySymbol);
useSymbol(mySymbol);

delete mySymbol; // No live references are left to mySymbol, so we can count on the garbage collector eliminating the entry in the weakMap when it runs (eventually)

列表12是根據(jù)上面鏈接的StackOverflow答案進行修改的。在這個示例中,目的是允許從外部調(diào)用者調(diào)用計數(shù)器,并在沒有引用時銷毀映射條目。代碼本身無法知道何時不再需要引用,如果使用普通的Map,將會導(dǎo)致內(nèi)存泄漏。這是因為即使在調(diào)用它的客戶端不再需要它之后,代碼仍然會保持對引用的持有。在這種情況下,我們使用WeakMap,可以依靠垃圾回收在沒有對鍵符號的引用時刪除映射條目。

結(jié)論

盡管2023年對于JavaScript來說相對較平靜,但ECMAScript 14添加了一些有用的功能,并使官方規(guī)范與現(xiàn)實世界保持同步。在下一個版本中,我們將會看到一系列的變化,包括一個全新的Temporal API用于處理日期和時間。

作者:Matthew Tyson

更多技術(shù)干貨盡在wx“云原生數(shù)據(jù)庫”

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容