大家好,我是若川。持續組織了8個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。歷史面試系列。另外:目前建有江西|湖南|湖北?籍 前端群,可加我微信進群。
今天聊 JavaScript
的最新提案,這是我 最新技術提案 專欄的第 16 篇文章了,感謝讀者們一如既往的支持!
開門見山,JavaScript
數組即將新增 4 個新的非破壞性方法:
.toReversed()
.toSorted()
.toSpliced()
.with()
Change Array by copy 提案

這四個方法來源于新的 Change Array by copy
提案,目前已經處于 stage3階段,意味著基本上不會再有太大變化了,我們即將在各大瀏覽器里看到它們的實現。
提案地址:https://github.com/tc39/proposal-change-array-by-copy
數組的破壞性和非破壞性
為啥這個提案叫 Change Array by copy
呢?字面意思就是從副本里改變數組。
這就要說起數組的破壞性和非破壞性方法了:
有些數組的方法我們在調用的時候不會改變原始的數組,我們稱它們為非破壞性方法,比如我們經常用到的 filter、some、map、find
等方法,斗是不會改變原數組的:

但是,另外有一些方法是會改變原數組本身的,比如:sort、reverse、splice
等方法。

可以看到,原數組和排序后得到的新數組是一樣的,說明這個方法改變了原數組。很多時候我們想用這些方法,但是又不想改變原數組,我們可能會先創建一個副本,比如下面這些操作:
const?sorted1?=?array1.slice().sort();
const?sorted2?=?[...array1].sort();
const?sorted3?=?Array.from(array1).sort();
幾個數組的新方法,就是用來解決這樣的問題的。
toSorted()
.toSorted()
是 .sort()
的非破壞性版本:
const?array?=?['c',?'o',?'n',?'a',?'r',?'d',?'l',?'i'];
const?result?=?array.toSorted();
console.log(result);?//??['a',?'c',?'d',?'i',?'l',?'n',?'o',?'r']
console.log(array);?//?['c',?'o',?'n',?'a',?'r',?'d',?'l',?'i']
下面是個簡單的 polyfill
:
if?(!Array.prototype.toSorted)?{Array.prototype.toSorted?=?function?(compareFn)?{return?this.slice().sort(compareFn);};
}
toReversed()
.toReversed()
是 .reverse()
的非破壞性版本:
const?array?=?['c',?'o',?'n',?'a',?'r',?'d',?'l',?'i'];
const?result?=?array.toReversed();
console.log(result);?//??['i',?'l',?'d',?'r',?'a',?'n',?'o',?'c']
console.log(array);?//?['c',?'o',?'n',?'a',?'r',?'d',?'l',?'i']
下面是個簡單的 polyfill
:
if?(!Array.prototype.toReversed)?{Array.prototype.toReversed?=?function?()?{return?this.slice().reverse();};
}
with()
with()
是對數組的某個元素賦值操作的非破壞性版本,比如下面的操作:
array[index]?=?value
如果我們只是想得到一個新數組,又不想改變原數組,可以這樣用:
const?array?=?['c',?'o',?'n',?'a',?'r',?'d',?'l',?'i'];
const?result?=?array.with(0,?'ConardLi')
console.log(result);?//??['ConardLi',?'o',?'n',?'a',?'r',?'d',?'l',?'i'];
console.log(array);?//?['c',?'o',?'n',?'a',?'r',?'d',?'l',?'i']
下面是個簡單的 polyfill
:
if?(!Array.prototype.with)?{Array.prototype.with?=?function?(index,?value)?{const?copy?=?this.slice();copy[index]?=?value;return?copy;};
}
toSpliced()
.splice(start, deleteCount, ...items)
方法比其他幾個破壞性方法更復雜點:
它從 start 開始刪除 deleteCount 個元素 ;
然后把 items 插入到被刪除的位置;
最后返回已刪除的元素。
const?array?=?[1,?2,?3,?4,?5,?6];
const?result?=?array.splice(1,?2,?0);
console.log(result);?//??[2,?3]
console.log(array);??//?[1,?0,?4,?5,?6]
.tospliced()
是 .splice()
的非破壞性版本,它會返回原數組變更后的版本,因此我們拿不到被刪除的元素:
const?array?=?[1,?2,?3,?4,?5,?6];
const?result?=?array.tospliced(1,?2,?0);
console.log(result);?//??[1,?0,?4,?5,?6]
console.log(array);??//?[1,?2,?3,?4,?5,?6]
下面是個簡單的 polyfill
:
if?(!Array.prototype.toSpliced)?{Array.prototype.toSpliced?=?function?(start,?deleteCount,?...items)?{const?copy?=?this.slice();copy.splice(start,?deleteCount,?...items);return?copy;};
}
polyfill
提案目前還在 stage3階段,在生產使用最好使用 polyfill
:
https://github.com/tc39/proposal-change-array-by-copy/blob/main/polyfill.js
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經堅持寫了8年,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助3000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
掃碼加我微信 ruochuan02、拉你進源碼共讀群
今日話題
目前建有江西|湖南|湖北?籍 前端群,想進群的可以加我微信 ruochuan12?進群。分享、收藏、點贊、在看我的文章就是對我最大的支持~