likes
comments
collection
share

2023款ECMAScript

作者站长头像
站长
· 阅读数 25

2023款ECMAScript

新的数组api

findLast

反向迭代数组,并返回满足提供的测试函数的第一个元素的值, 如果没有找到返回undefined

const isEven = (number) => number % 2 === 0;
const numbers = [1234];
console.log(numbers.findLast(isEven)); // 4

findLastIndex

反向迭代数组,并返回满足所提供的测试函数的第一个元素的索引。若没有找到对应元素,则返回 -1

const isEven = (number) => number % 2 === 0;
const numbers = [1234];
console.log(numbers.findLastIndex(isEven)); // 3

如果预计查找的元素靠后,使用findLast和findLastIndex 可以减少查询次数,提高程序效率。

toSorted

sort方法的复制版本,复制原数组,然后对新数组排序,并返回新数组。

排序逻辑和参数都和sort方法一样

const array = [321];
const sortedArray = array.toSorted();
console.log(sortedArray); // [1, 2, 3]
console.log(array); // 原数组不变 [3, 2, 1]

toReversed

reverse方法的复制版本;复制数组原数组,对新数组颠倒顺序,并返回新数组。

const original = [1234];
const reversed = original.toReversed();
console.log(original);  // [ 1, 2, 3, 4 ] 原数组不变
console.log(reversed);  // [ 4, 3, 2, 1 ]

toSpliced

splice() 方法的复制版本。它返回一个新数组,并在给定的索引处删除和/或替换了一些元素。

  const original = ["Jan""Mar""Apr""May"];
  // 在索引 1 处添加一个元素
  const spliced = months.toSpliced(10"Feb");
  console.log(spliced); // ["Jan""Feb""Mar""Apr""May"]
  console.log(original); // ["Jan""Mar""Apr""May"]  原数组不变

with

使用方括号表示法修改指定索引值的复制方法版本

const arr = [12345];
console.log(arr.with(26)); // [1, 2, 6, 4, 5]
console.log(arr); // [1, 2, 3, 4, 5] 原数组不变

📌toSorted、toReversed、toSpliced、with在处理数组的时候会将稀疏数组的空值转成undefined

const arr = [1, , 34, , 6];
console.log(arr.with(0, 2)); // [2, undefined, 3, 4, undefined, 6]

📌toSorted、toReversed、toSpliced、with可以使用call或者apply在类数组对象上应用

  function fn1(){
    console.log(Array.prototype.with.call(arguments,2,6)); // [1,2,6,4,5]
  }
  fn1(1,2,3,4,5)
  
  const arrayLike = {
    length3,
    unrelated"foo",
    05,
    24,
  };
  console.log(Array.prototype.with.call(arrayLike, 01));
  // [ 1, undefined, 4 ]

toSorted、toReversed、toSpliced、with在实际工作中是非常有用的,尤其在react中使用immutable data进行状态更新的时候, 这四个api能很大程度简化操作,下面的例子是一个简单的todo组件例子。

function App(){
    const [items,setItems] = React.useState([{id:1,text:'学习',done:false},{id:2,text:'吃饭',done:false},{id:3,text:'睡觉',done:false}]);
    const removeItem = (index)=>{
      // 方法一 使用splice
      // setItems((prev)=>{
      //   const copy = [...prev];
      //   copy.splice(index,1);
      //   return copy;
      // })
      // 方法二 使用filter
      // setItems(prev=>prev.filter((_,i)=>i !== index ))
      // 方法三 使用toSpliced
      setItems(prev=>prev.toSpliced(index,1));
    }
    const toggleStatus = (index)=>{
      // 方法一 使用map
      // setItems(prev=>prev.map((item,i)=>{
      //   if(index === i){
      //     return {
      //       ...item,
      //       done: !item.done
      //     }
      //   }
      //   return item;
      // }))

      // 使用with
      setItems(prev=>prev.with(index, {
        ...prev[index],
        done: !prev[index].done
      }))
    }
    return (
      <div>
        {
          items.map((i,index)=>{
            return (
              <div key={i.id}>
                <input type="checkbox" checked={i.done} onChange={()=>toggleStatus(index)}/>
                <span>{i.text}</span>
                <button onClick={()=>removeItem(index)}>删除</button>
              </div>
            )
          })
        }
      </div>
    )
  }

WeakMap 支持 Symbol 作为键

const weak = new WeakMap();
const key = Symbol("ref");
weak.set(key"ECMAScript 2023");

console.log(weak.get(key)); // ECMAScript 2023

Hashbang

这个在nodejs中已经早就应用了,其实规范落地没什么影响。

#!/usr/bin/env node

console.log('hi');

兼容性

开发环境支持:

目前最新版的ts支持findLast和findLastIndex, 但是还不支持toSpliced、toSorted、toReversed、with,在typescript仓库中已经有人提了pull request;如果等不及官方支持,可在项目中给global的Array添加对应的类型定义,参考pr:

github.com/microsoft/T…

2023款ECMAScript

常用编辑器vscode和webstorm中语法还未支持,没有相关的语法提示,并且会有警告提示。

浏览器支持:

2023款ECMAScript

polyfill

目前core-js已经支持数组的api, 但尚不支持WeakMap使用Symbol作为key来使用。

参考

github.com/tc39/propos…

参考资料

[1]

add change array by copy types: github.com/microsoft/T…

[2]

TC39 Finished Proposals: github.com/tc39/propos…