news 2026/3/5 9:42:48

JavaScript数组方法全解析:返回值与是否改变原数组详解(附实例)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript数组方法全解析:返回值与是否改变原数组详解(附实例)

在前端开发中,JavaScript 数组是使用频率极高的数据结构。掌握数组的各种方法不仅能提升开发效率,还能避免因误用而导致的 bug。本文将系统性地梳理常用数组方法,重点说明每个方法是否会修改原数组以及返回什么类型的值,并辅以清晰示例,助你彻底掌握数组操作。


📌 分类说明

我们将数组方法分为两大类:

  • 会改变原数组的方法(Mutating Methods)
  • 不会改变原数组的方法(Non-Mutating / Pure Methods)

⚠️ 注意:有些方法虽然不改变原数组,但若数组元素是引用类型(如对象、数组),其内部属性仍可能被修改。


🔁 一、会改变原数组的方法(Mutating)

1.push()

  • 作用:向数组末尾添加一个或多个元素
  • 返回值:新数组的长度(number
  • 是否改变原数组:✅ 是
let arr = [1, 2]; let len = arr.push(3, 4); console.log(arr); // [1, 2, 3, 4] console.log(len); // 4

2.pop()

  • 作用:删除数组最后一个元素
  • 返回值:被删除的元素(若数组为空则返回undefined
  • 是否改变原数组:✅ 是
let arr = [1, 2, 3]; let last = arr.pop(); console.log(arr); // [1, 2] console.log(last); // 3

3.shift()

  • 作用:删除数组第一个元素
  • 返回值:被删除的元素(空数组返回undefined
  • 是否改变原数组:✅ 是
let arr = [1, 2, 3]; let first = arr.shift(); console.log(arr); // [2, 3] console.log(first); // 1

4.unshift()

  • 作用:在数组开头添加一个或多个元素
  • 返回值:新数组的长度
  • 是否改变原数组:✅ 是
let arr = [2, 3]; let len = arr.unshift(0, 1); console.log(arr); // [0, 1, 2, 3] console.log(len); // 4

5.splice(start, deleteCount, ...items)

  • 作用:从指定位置删除/替换/添加元素
  • 返回值:被删除的元素组成的数组(若未删除则返回空数组)
  • 是否改变原数组:✅ 是
let arr = [1, 2, 3, 4]; let removed = arr.splice(1, 2, 'a', 'b'); console.log(arr); // [1, 'a', 'b', 4] console.log(removed); // [2, 3]

6.reverse()

  • 作用:反转数组元素顺序
  • 返回值:反转后的数组(注意:是原数组的引用
  • 是否改变原数组:✅ 是
let arr = [1, 2, 3]; let reversed = arr.reverse(); console.log(arr); // [3, 2, 1] console.log(reversed); // [3, 2, 1] — 与 arr 指向同一数组

7.sort([compareFunction])

  • 作用:对数组元素进行排序(默认按字符串 Unicode 码)
  • 返回值:排序后的数组(原数组的引用
  • 是否改变原数组:✅ 是
let arr = [3, 1, 2]; arr.sort((a, b) => a - b); console.log(arr); // [1, 2, 3]

💡 提示:若要不改变原数组排序,请先用slice()[...arr]复制一份再排序。


8.fill(value, start, end)

  • 作用:用指定值填充数组某段区间
  • 返回值:被填充后的数组(原数组引用)
  • 是否改变原数组:✅ 是
let arr = [1, 2, 3, 4]; arr.fill(0, 1, 3); console.log(arr); // [1, 0, 0, 4]

9.copyWithin(target, start, end)

  • 作用:浅复制数组的一部分到同一数组的其他位置
  • 返回值:修改后的数组(原数组引用)
  • 是否改变原数组:✅ 是
let arr = [1, 2, 3, 4, 5]; arr.copyWithin(0, 3, 5); // 将索引3~4的元素复制到开头 console.log(arr); // [4, 5, 3, 4, 5]

🧼 二、不会改变原数组的方法(Non-Mutating)

1.concat(...arrays)

  • 作用:合并两个或多个数组
  • 返回值:新数组
  • 是否改变原数组:❌ 否
let arr1 = [1, 2]; let arr2 = [3, 4]; let newArr = arr1.concat(arr2); console.log(arr1); // [1, 2](不变) console.log(newArr); // [1, 2, 3, 4]

✅ 推荐使用扩展运算符替代:[...arr1, ...arr2]


2.slice(start, end)

  • 作用:提取数组片段
  • 返回值:新数组(浅拷贝)
  • 是否改变原数组:❌ 否
let arr = [1, 2, 3, 4]; let part = arr.slice(1, 3); console.log(arr); // [1, 2, 3, 4](不变) console.log(part); // [2, 3]

3.map(callback)

  • 作用:对每个元素调用函数,生成新数组
  • 返回值:转换后的新数组
  • 是否改变原数组:❌ 否
let arr = [1, 2, 3]; let doubled = arr.map(x => x * 2); console.log(arr); // [1, 2, 3](不变) console.log(doubled); // [2, 4, 6]

4.filter(callback)

  • 作用:筛选满足条件的元素
  • 返回值:新数组
  • 是否改变原数组:❌ 否
let arr = [1, 2, 3, 4]; let evens = arr.filter(x => x % 2 === 0); console.log(arr); // [1, 2, 3, 4](不变) console.log(evens); // [2, 4]

5.reduce(callback, initialValue)

  • 作用:累积计算,归并为单个值
  • 返回值:累积结果(类型由回调决定)
  • 是否改变原数组:❌ 否
let arr = [1, 2, 3]; let sum = arr.reduce((acc, val) => acc + val, 0); console.log(arr); // [1, 2, 3](不变) console.log(sum); // 6

6.find(callback)

  • 作用:查找第一个满足条件的元素
  • 返回值:找到的元素(未找到返回undefined
  • 是否改变原数组:❌ 否
let arr = [{id: 1}, {id: 2}]; let item = arr.find(x => x.id === 2); console.log(item); // {id: 2}

7.findIndex(callback)

  • 作用:查找第一个满足条件的元素索引
  • 返回值:索引(未找到返回-1
  • 是否改变原数组:❌ 否

8.every(callback)/some(callback)

  • 作用:判断所有/部分元素是否满足条件
  • 返回值boolean
  • 是否改变原数组:❌ 否
[1, 2, 3].every(x => x > 0); // true [1, 2, 3].some(x => x > 2); // true

9.includes(value, fromIndex)

  • 作用:判断数组是否包含某值
  • 返回值boolean
  • 是否改变原数组:❌ 否

10.indexOf(value)/lastIndexOf(value)

  • 作用:查找元素首次/最后一次出现的索引
  • 返回值:索引(未找到返回-1
  • 是否改变原数组:❌ 否

11.join(separator)

  • 作用:将数组转为字符串
  • 返回值:字符串
  • 是否改变原数组:❌ 否
['a', 'b', 'c'].join('-'); // "a-b-c"

12.flat(depth)

  • 作用:扁平化嵌套数组
  • 返回值:新数组
  • 是否改变原数组:❌ 否
[[1, 2], [3, [4]]].flat(2); // [1, 2, 3, 4]

13.flatMap(callback)

  • 作用:先 map 再 flat(深度为1)
  • 返回值:新数组
  • 是否改变原数组:❌ 否
['a b', 'c d'].flatMap(s => s.split(' ')); // ['a', 'b', 'c', 'd']

📊 总结表格

方法是否改变原数组返回值类型
push/pop/shift/unshiftnumber(长度)或元素
splice被删除元素组成的数组
reverse/sort/fill/copyWithin原数组引用
concat/slice/map/filter/flat/flatMap新数组
reduce/find/findIndex累积值 / 元素 / 索引
every/some/includesboolean
joinstring
indexOf/lastIndexOfnumber

✅ 最佳实践建议

  1. 优先使用不可变方法(如map,filter),便于调试和状态管理(尤其在 React/Vue 中)。
  2. 若需修改原数组,明确意图;否则使用[...arr]arr.slice()创建副本后再操作。
  3. 对于排序,避免直接arr.sort(),推荐:
    const sorted = [...arr].sort((a, b) => a - b);

📚 结语

掌握数组方法的“副作用”(是否改变原数组)是写出健壮前端代码的关键。希望本文能成为你日常开发的速查手册。欢迎收藏、点赞、评论交流!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/4 3:40:36

Java 中 SPI(Service Provider Interface)机制的使用场景

先快速回顾 SPI 核心逻辑SPI 的核心流程:定义服务接口(如java.sql.Driver);第三方实现该接口(如 MySQL 驱动com.mysql.cj.jdbc.Driver);实现方在META-INF/services/目录下创建以 “接口全类名”…

作者头像 李华
网站建设 2026/2/28 19:36:18

【GESP】C++五级/四级练习题 luogu-P1413 坚果保龄球

GESP C 五级/四级练习题,贪心思想思想考点,四级考生也可以练习,因为难度不大。题目难度⭐⭐★☆☆,适合五级入门和四级练习,洛谷难度等级普及-。 luogu-P1413 坚果保龄球 题目要求 题目描述 题目题解详见&#xff1…

作者头像 李华
网站建设 2026/3/4 1:11:08

复杂表格识别技术

在数字化转型浪潮中,大量关键数据仍以复杂表格形式存在于财务报表、医疗报告、物流单据、学术论文等各类文档中。这些表格结构多样、格式复杂,传统OCR技术往往只能识字却难以理解表格的结构与语义关系,给数据的高效提取和利用带来了巨大挑战。…

作者头像 李华
网站建设 2026/3/2 21:23:44

测完这批工具 10个AI论文网站深度测评与推荐 MBA毕业论文写作必备

在当前学术研究日益依赖AI工具的背景下,MBA学生和研究人员面临着论文写作效率低、格式规范难掌握、文献资料查找繁琐等多重挑战。为了帮助用户更高效地完成高质量的毕业论文,笔者基于2026年的实际测评数据与真实用户反馈,对市面上主流的10个A…

作者头像 李华
网站建设 2026/3/2 8:46:24

6-MySQL

MySQL安装 在前面的案例中,我们将数据存储在.txt文件中,这不便维护与管理。在实际的项目中,数据会存储在专业的数据库里。 数据库管理系统:DataBase Management System(DBMS),操作和管理数据库的大型软件。 SQL&…

作者头像 李华