别再用老办法了,这几个数组新API更好用

摘要:写JavaScript的时候,你是不是还在用for循环倒着找东西?或者写[...arr].reverse()来反转数组?其实有更简单的办法。从2022年开始,JavaScript加了好几个数组的新方法。这些方法能让你少写很多代码,还不容易出错。

写JavaScript的时候,你是不是还在用for循环倒着找东西?或者写[...arr].reverse()来反转数组?其实有更简单的办法。

从2022年开始,JavaScript加了好几个数组的新方法。这些方法能让你少写很多代码,还不容易出错。Vue、React、微信小程序、Node.js都能用。


四个最有用的数组新方法

需求老写法新写法
从末尾找第一个匹配的元素手动写for循环倒着找findLast()
从末尾找第一个匹配的索引倒着遍历记住位置findLastIndex()
反转数组但不改原数组[...arr].reverse()toReversed()
拿最后一个元素arr[arr.length - 1]at(-1)

用上新方法,代码能少写一大半,逻辑也清楚多了。


一、findLast:从后面开始找

假设你有一个消息列表,想找最后一条已读的消息。老办法得自己写循环倒着找:

const messages = [
  { id: 1, read: false },
  { id: 2, read: true },
  { id: 3, read: false },
  { id: 4, read: true }
];

// 老写法
let lastRead = null;
for (let i = messages.length - 1; i >= 0; i--) {
  if (messages[i].read) {
    lastRead = messages[i];
    break;
  }
}

// 新写法
const lastRead = messages.findLast(msg => msg.read);
console.log(lastRead); // { id: 4, read: true }

在Vue3里这样用:

<script setup>
import { ref } from 'vue'

const logs = ref([
  { level: 'info' },
  { level: 'error' },
  { level: 'warn' },
  { level: 'error' }
])

// 找最后一个error日志
const lastError = logs.value.findLast(log => log.level === 'error')
</script>


二、findLastIndex:找最后一个匹配的位置

比如你有一个任务列表,想删掉最后一个包含"买"字的任务。用findLastIndex可以快速定位:

const tasks = ['买牛奶', '遛狗', '买面包', '打电话', '买鸡蛋'];

// 找最后一个包含"买"的任务在哪
const lastIndex = tasks.findLastIndex(task => task.includes('买'));

if (lastIndex !== -1) {
  tasks.splice(lastIndex, 1); // 删掉"买鸡蛋"
}

console.log(tasks);
// ['买牛奶', '遛狗', '买面包', '打电话']

这个方法不会把整个数组都找一遍,找到就停,比老办法快。


三、toReversed:反转但不改原数组

reverse()这个方法有个坑:它会直接改掉原来的数组。很多时候你只是想拿反转后的结果用一下,并不想动原始数据。

const original = [1, 2, 3, 4, 5];

// reverse会改原数组
const reversed1 = original.reverse();
console.log(original); // [5, 4, 3, 2, 1] 原数组变了

// toReversed不改原数组
const reversed2 = original.toReversed();
console.log(original); // [1, 2, 3, 4, 5] 没问题
console.log(reversed2); // [5, 4, 3, 2, 1]

在React里用很方便,不用担心改了父组件传进来的数据:

function MessageList({ messages }) {
  // 安全反转,不影响原来的messages
  const reversedMessages = messages.toReversed();

  return (
    <ul>
      {reversedMessages.map(msg => <li key={msg.id}>{msg.text}</li>)}
    </ul>
  );
}


四、at:用负数拿后面的元素

想拿数组最后一个元素,老得写arr[arr.length - 1],又长又容易写错。at方法支持负数索引,-1是最后一个,-2是倒数第二个。

const arr = ['a', 'b', 'c', 'd', 'e'];

const last = arr.at(-1);      // 'e'
const secondLast = arr.at(-2); // 'd'
const first = arr.at(0);       // 'a'

at也能用在字符串上:

'hello'.at(-1)  // 'o'


容易踩的四个坑

坑一:找的方向搞反

想找第一个匹配的用find(),想找最后一个用findLast(),别弄混了。

坑二:以为toReversed会改原数组

toReversed不改原数组。如果你确实想改原数组,那还是用reverse()。

坑三:at超出范围返回undefined

const arr = [1, 2];
console.log(arr.at(10));  // undefined,不报错
console.log(arr.at(-10)); // undefined

用的时候记得判断一下返回值是不是undefined。

坑四:兼容性问题

这几个方法主流环境都支持:

  • Chrome 92以上

  • Firefox 90以上

  • Safari 15.4以上

  • Node.js 16以上

  • 微信小程序基础库2.24.0以上

只有IE不支持。如果你的项目还要兼容老环境,装一个core-js就行:

pnpm add core-js@3

然后在入口文件最上面引入:

import 'core-js/stable';

之后新语法就能正常跑了。


总结

这四个方法都不复杂,但用起来确实顺手。findLast和findLastIndex帮你省掉倒着写循环的麻烦,toReversed让你不用担心改错原数组,at让拿最后一个元素变得简单。

下次写代码的时候,试试这几个新方法,能少写不少代码。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_13712