4

JavaScript 数组新增 4 个非破坏性方法!

 2 years ago
source link: https://www.fly63.com/article/detial/11352
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

开门见山,JavaScript 数组即将新增 4 个新的非破坏性方法:

  • .toReversed()
  • .toSorted()
  • .toSpliced()
  • .with()

Change Array by copy 提案

625cbd8e8b437.jpg

这四个方法来源于新的 Change Array by copy 提案,目前已经处于 stage3阶段,意味着基本上不会再有太大变化了,我们即将在各大浏览器里看到它们的实现。

提案地址:https://github.com/tc39/proposal-change-array-by-copy

数组的破坏性和非破坏性

为啥这个提案叫 Change Array by copy 呢?字面意思就是从副本里改变数组。

这就要说起数组的破坏性和非破坏性方法了:

有些数组的方法我们在调用的时候不会改变原始的数组,我们称它们为非破坏性方法,比如我们经常用到的 filter、some、map、find 等方法,斗是不会改变原数组的:

625cbd93ddc54.jpg

但是,另外有一些方法是会改变原数组本身的,比如:sort、reverse、splice 等方法。

625cbd9817edd.jpg

可以看到,原数组和排序后得到的新数组是一样的,说明这个方法改变了原数组。很多时候我们想用这些方法,但是又不想改变原数组,我们可能会先创建一个副本,比如下面这些操作:

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

作者:ConardLi, 来源:code秘密花园

链接: https://www.fly63.com/article/detial/11352


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK