瀏覽器最近獲得了新的互通方法,您可以呼叫陣列:Array.prototype.with()
。
本文將探討這個方法的運作方式,以及如何在不變更原始陣列的情況下更新陣列。
Array.prototype.with(index, value)
簡介
Array.prototype.with(index, value)
方法會傳回函式呼叫的陣列副本,並將 index
設為您提供的新 value
。
以下範例顯示年齡陣列。您想要建立陣列的新副本,同時將第二個年齡從 15 變更為 16:
const ages = [10, 15, 20, 25];
const newAges = ages.with(1, 16);
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 15, 20, 25] (unchanged)
細分程式碼:ages.with(...)
會傳回 ages
變數的副本,不會修改原始陣列。ages.with(1, …)
會取代第二個項目 (index = 1
)。ages.with(1, 16)
會將第二個項目指派給 16
。
透過這種方式,您可透過修改的方式建立陣列的新副本。
如要確保原始陣列保持不變,這項功能就很實用,而本文將介紹一些相關用途。但就目前而言,看看您在使用括號標記法時的情形。
const ages = [10, 15, 20, 25];
const newAges = ages;
newAges[1] = 16;
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 16, 20, 25] (Also changed 🙁)
如您所見,在此範例中也修改了 ages
變數。這是因為指派 ages = newAges
時,JavaScript 不會複製陣列,而是建立另一個陣列的參照。因此,其中一項變更也會影響其他變更,因為兩者都指向同一個陣列。
Array.prototype.with() 和不變性
許多前端程式庫和架構的核心為不變動 包括 React (和 redux) 和 Vue
此外,其他程式庫和架構不一定需要不變性,但可以採取相應做法來提升效能:Angular 和 Lit
因此,開發人員經常必須使用其他方法來傳回陣列副本,以達到程式碼可讀性的目的:
const ages = [10, 15, 20, 25];
const newAges = ages.map((age, index) => {
if (index === 1) {
return 16;
}
return age;
});
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 15, 20, 25] (Remains unchanged)
以下範例程式碼說明如何在 React 中使用 .with()
與 useState,以不可變更的方式更新項目的陣列:
.with()
方法會傳回陣列的副本,因此您可以將多個 .with()
呼叫,甚至是其他陣列方法建立鏈結。以下範例說明如何增加陣列中的第二個和第三個年齡:
const ages = [10, 15, 20, 25];
const newAges = ages.with(1, ages[1] + 1).with(2, ages[2] + 1)
console.log(newAges); // [10, 16, 21, 25]
console.log(ages); // [10, 15, 20, 25] (unchanged)
其他新的不可變動方法
最近還有另外三種方法可以互通:
Array.prototype.toReversed()
:在不變更原始陣列的情況下反轉陣列。Array.prototype.toSorted()
:可在不變更原始陣列的情況下排序陣列。Array.prototype.toSpliced()
,運作方式與.splice()
類似,但不會變更原始陣列。
這三種方法的根據 MDN 是其對應項目的複製版本。在預期或偏好的不變性時,這些方法也能使用。
總結來說,如果使用本文所述的四種方法,就能更輕鬆地在 JavaScript 中變更不可變更的更新。具體來說,.with()
方法可讓您在不變更原始陣列的情況下,輕鬆更新陣列的單一元素。