?JavaScript在持續發展,近期ECMAScript 14中發布添加了一批新功能,讓我們一起來探索一下今年對JavaScript開發人員的新功能。時間的車輪又過去了一年,隨之而來的是JavaScript的新官方版本:ECMAScript 2023,也被稱為ECMAScript 14。今年的改進包括對數組的添加和對ECMAScript文件中shebang的支持,以及對弱集合的符號鍵的擴展。這些變化主要是對語言的細化改進,而不是什么重大的變革。然而,這些改變的綜合效果是繼續推進語言的發展。下面是JavaScript在2023年的新功能概覽演示。
理解規范
ECMAScript規范是一份令人印象深刻的文檔,既是開發人員和教育者的基本參考,也是JavaScript引擎實現者的官方技術規范。這是一個相當平衡的過程,規范處理得很好。由于包含了大量的信息,它作為語言的用戶指南可能有些繁瑣。
關于規范的另一個要了解的事情是,它實際上是一個活動的文檔,在語言在實際應用中使用時會不斷發展。通常情況下,新功能在被用戶社區非正式接受后才會被添加到官方規范中。例如,今年的shebang語法就是一個例子。一旦一個功能被規范所編碼和標準化,規范就成為進一步創新該功能的新穩定基礎。
有時,ECMAScript規范引入了開創性的想法。一個例子是采用了受C#影響的/語法。async/await 作為一種語言,JavaScript已經從復制粘貼的鼠標懸停效果的時代飛躍而來。ECMAScript規范過程在這一演變中起到了巨大的作用。
現在,讓我們來看看在2023年引入的JavaScript的新功能。
數組原型對象的toSorted方法
讓我們從新的數組方法toSorted()開始。toSorted()具有與sort()相同的簽名,但它創建一個新的數組,而不是在原數組上進行操作。下面是列表1中的新數組方法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()一樣,也接受一個可選的參數,即比較函數。例如,我們可以使用toSorted()創建一個按降序排列的新數組,如列表2所示。
列表2. 使用比較函數
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()也可以應用于對象數組。在這種情況下,您必須提供一個使用對象上的數據的比較函數,因為對象沒有自然的排序方式。您可以在列表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()的復制版本。列表4中有一些使用toReversed()的快速示例,包括將其應用于帶有比較函數的對象。
列表4. 使用toReversed()
["a","b","c","d","e"].toReversed(); // ['e', 'd', 'c', 'b', 'a']
Array.prototype.with新的with()方法允許您根據索引修改單個元素,并返回一個新的數組。因此,如果您知道索引和新值,這個方法非常方便。請注意,with()是set()的復制伴侶。列表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方法允許您從數組中獲取最后一個匹配元素的實例。如果沒有找到匹配的元素,則返回undefined。在列表6中給出了一個簡單的示例,我們從數組中獲取最后一個偶數。
列表6. 使用findLast()方法的示例
onst arr = [54, 34, 55, 75, 98, 77];
?
const lastEvenIndex = arr.findLast((element) => {return element % 2 === 0;
});
?
console.log(lastEvenIndex); // 98
findLast()還支持傳入一個" "來設置上下文。也就是說,第二個參數將告訴第一個參數函數關鍵字將指向什么。您可以在列表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到目前為止,我們描述的所有方法也適用于。最后一個新的數組方法toSpliced()只存在于。該方法是JavaScript數組操作的復制版本——這是一種熟悉的瑞士軍刀。拼接TypedArrayArraytoSpliced () ()假設我們有一個顏色數組,我們需要在中間插入兩個新顏色(粉色和青色)。可以在清單9中看到這一點。記住,這會創建一個新數組,而不是修改原來的數組。
列表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說法,表示一個標簽后面跟著一個感嘆號(其中“bang”是“!”的俚語)。自古以來,在文件開頭的注釋就會告訴shell這里是一個可執行腳本,以及使用什么引擎來運行它。
列表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中的代碼告訴操作系統使用node
程序來運行這個腳本。現在,你可以直接輸入命令來運行它。如果沒有Shebang注釋,../hello.js
這樣是行不通的。Shebang支持是規范中的一個功能更新,已經在多個上下文中非官方地采用和實現。ECMAScript 14中的最后一個新功能是擴展了可以用作弱引用集合鍵的內容。與日常JavaScript用法相比,弱引用集合有點晦澀。在編程中,弱引用是指如果它本來應該被垃圾回收,那么它將被丟棄。換句話說,單獨的弱引用不足以阻止垃圾回收算法將引用目標丟棄(這就是為什么它是弱引用)。你可以在這里了解更多關于弱引用以及它們何時有用的信息。這里也有一個很好的討論。?ES14允許在集合中使用大多數符號作為鍵,而以前只能使用對象。如果你想知道什么是符號,你并不孤單。你可以在這里了解更多關于符號的信息。這個新功能本質上使得在集合中使用弱引用更加容易,通過放寬可以用作鍵的限制。列表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 timeif(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是根據上面鏈接的StackOverflow答案進行修改的。在這個示例中,目的是允許從外部調用者調用計數器,并在沒有引用時銷毀映射條目。代碼本身無法知道何時不再需要引用,如果使用普通的Map
,將會導致內存泄漏。這是因為即使在調用它的客戶端不再需要它之后,代碼仍然會保持對引用的持有。在這種情況下,我們使用WeakMap
,可以依靠垃圾回收在沒有對鍵符號的引用時刪除映射條目。
結論
盡管2023年對于JavaScript來說相對較平靜,但ECMAScript 14添加了一些有用的功能,并使官方規范與現實世界保持同步。在下一個版本中,我們將會看到一系列的變化,包括一個全新的Temporal API用于處理日期和時間。
作者:Matthew Tyson
更多技術干貨請關注公眾號“云原生數據庫”
squids.cn,目前可體驗全網zui低價RDS,免費的遷移工具DBMotion、SQL開發工具等。