前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库splice 与 slice 修改原数组区别
JavaScript数组与集合

splice 和 slice 有什么区别,哪个会改原数组?

slice(start, end) 截取一段返回新数组,原数组不动;splice(start, count, ...items) 在原数组上删除、插入或替换,返回被删掉的元素。最容易混的是第二个参数:slice 是结束位置,splice 是删几个。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#数组与集合
先看核心答案读代码示例
理解线索

一个是复印,一个是动刀

  1. slice(start, end)从 start 截到 end 前一位,返回副本
  2. splice(start, count)从 start 起删掉 count 个,返回被删的元素
  3. splice(start, 0, ...items)删除个数为 0 时,就是在 start 位置插入

splice 的返回值永远是被删掉的那部分,不是修改后的数组。只插入不删除时,它返回的是空数组。

核心回答

先记住这个答案

两者有三个区别。第一,slice 不修改原数组,返回截取出来的新数组;splice 直接修改原数组。第二,参数含义不同,slice(start, end) 的第二个参数是结束索引,而且不包含这个位置,splice(start, count, ...items) 的第二个参数是要删除的个数,后面还能跟要插入的元素。第三,返回值不同,slice 返回截取的部分,splice 返回被删掉的元素组成的数组。

  • slice 不改原数组,splice 改原数组
  • slice 第二参数是结束索引,不包含该位置
  • splice 第二参数是删除个数,返回被删元素
  • 想要不改原数组的 splice,用 toSpliced()

同一个数组上分别调用

把两个方法用同样的数字参数调一遍,参数含义的差别就很清楚了。

截取、删除和插入JavaScript
const arr = [1, 2, 3, 4, 5]

const part = arr.slice(1, 3)       // 从索引 1 截到索引 3 之前
console.log(JSON.stringify(part), JSON.stringify(arr))

const removed = arr.splice(1, 3)   // 从索引 1 开始删 3 个
console.log(JSON.stringify(removed), JSON.stringify(arr))

arr.splice(1, 0, 'a', 'b')         // 删 0 个,在索引 1 插入两个
console.log(JSON.stringify(arr))
查看输出与解释
[2,3] [1,2,3,4,5]
[2,3,4] [1,5]
[1,"a","b",5]

同样传 (1, 3) 这两个参数,slice 取的是索引 1 和 2 两个元素,原数组完整保留;splice 删掉了索引 1 开始的三个元素,原数组只剩 [1, 5]。最后一次 splice 删除个数为 0,只做插入,这是往数组中间加元素的标准写法。 记忆方法:slice 像复印一段,原件不动;splice 像在原件上动刀,切下来的部分交给你。

负数索引和省略参数

两个方法的 start 都支持负数,表示从末尾倒数,-1 是最后一个元素。所以 arr.slice(-2) 取最后两个,arr.splice(-1, 1) 删掉最后一个。slice 的 end 也可以是负数,arr.slice(0, -1) 就是去掉最后一个元素后的副本。

常见的省略写法
slice() 不传参数时复制整个数组,是老代码里常见的浅拷贝写法。splice(start) 只传一个参数时,会从 start 一直删到末尾,这点很容易被忽略,本来只想删一个,结果后面全没了。替换元素可以一步完成,arr.splice(2, 1, 'x') 就是把索引 2 换成 'x'。 另外,字符串也有 slice,用法和数组一样;但字符串没有 splice,因为字符串不可修改。
回答前,多想一步

容易答错的地方

以为 splice 返回修改后的数组
splice 返回的是被删掉的元素。写成 const next = arr.splice(1, 1) 再去渲染 next,拿到的是被删掉的那一项。修改后的结果就在 arr 本身。
把 slice 的第二个参数当成个数
arr.slice(2, 3) 只取一个元素,不是从索引 2 开始取三个。slice 的两个参数都是位置,取的是左闭右开的区间。
在 React state 上直接用 splice
splice 改的是原数组,引用没变,React 可能不会重新渲染。删除某一项要写成 list.filter((_, i) => i !== index),或者用不修改原数组的 toSpliced。
试着用自己的话回答

面试官还会怎么问?

有没有不改原数组的 splice?

ES2023 新增了 toSpliced(),参数和 splice 完全一样,但返回的是修改后的新数组,原数组不动。注意它的返回值和 splice 不同:它返回修改后的整个数组,不是被删掉的元素。

删除数组某一项,用 splice 还是 delete?

用 splice。delete arr[i] 只是删掉这个索引上的属性,数组长度不变,中间留下一个空位;splice(i, 1) 会把后面的元素往前挪,长度减 1。

splice 删除中间元素的性能怎样?

删除或插入后,后面的元素都要挪位置,所以是 O(n)。在很长的数组里频繁删除中间元素开销会比较大,这种场景可以考虑先标记再统一 filter,或者换成更合适的数据结构。

从一道题,走向一组知识

把知识连起来

数组与集合

sort 会改原数组吗?不想改原数组该怎么排序?

splice 和 sort 都会原地修改数组,那篇讲怎样在不改原数组的前提下拿到结果。

数组与集合

flat 默认展开几层?flatMap 和先 map 再 flat 有什么不同?

flat 和 slice 一样返回新数组不动原数组,可以一起归到不修改原数组的那组方法里记。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • Array.prototype.slice()
  • Array.prototype.splice()

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 同一个数组上分别调用
  3. 负数索引和省略参数
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑