JavaScript数组slice方法教程详解
编程并不是一个机械性的工作,而是需要有思考,有创新的工作,语法是固定的,但解决问题的思路则是依靠人的思维,这就需要我们坚持学习和更新自己的知识。今天golang学习网就整理分享《JavaScript数组slice方法详解及使用教程》,文章讲解的知识点主要包括,如果你对文章方面的知识点感兴趣,就不要错过golang学习网,在这可以对大家的知识积累有所帮助,助力开发能力的提升。
JavaScript的Array.prototype.slice方法用于从现有数组中提取指定索引范围的元素并生成新数组,且不会修改原数组。1. 它接受两个可选参数begin和end,begin指定开始索引(默认为0,负数表示从末尾倒数),end指定结束索引(不包含该索引元素,默认为数组末尾);2. 返回一个包含提取元素的新数组,原数组保持不变;3. 常用于数组复制、子集提取、类数组对象转换等场景;4. 在处理稀疏数组时保留空槽,在处理非数组对象时可通过call或apply将其转换为数组。
JavaScript的Array.prototype.slice
方法,简单来说,就是一个用来从现有数组中“切”出一段内容,然后生成一个全新的数组的方法。它不会改变原始数组,这很重要。

解决方案
Array.prototype.slice()
方法的精髓在于它的非破坏性(non-mutating)。它允许你基于一个数组的某个部分,创建一个浅拷贝(shallow copy)的新数组。想象一下你有一条长长的面条,slice
就是剪刀,你剪下了一段,但原来的面条还在那里,并没有变短。
这个方法的语法是 arr.slice([begin[, end]])
。

begin
(可选):指定开始提取元素的索引。- 如果省略,
slice
会从索引 0 开始。 - 如果是负数,它会从数组的末尾开始计算,例如
-1
表示倒数第一个元素,-2
表示倒数第二个,以此类推。 - 如果
begin
超出数组的长度,结果会是一个空数组。
- 如果省略,
end
(可选):指定结束提取元素的索引(不包含该索引处的元素)。- 如果省略,
slice
会提取到数组的末尾。 - 如果是负数,同样从数组末尾计算。
- 如果
end
小于或等于begin
,或者end
超出数组长度,结果通常会是一个空数组(除非begin
也超出了)。
- 如果省略,
slice
方法返回一个包含提取元素的新数组。
看几个例子可能更直观:

const originalArray = ['apple', 'banana', 'orange', 'grape', 'kiwi']; // 1. 完整复制一个数组 const fullCopy = originalArray.slice(); console.log(fullCopy); // ['apple', 'banana', 'orange', 'grape', 'kiwi'] console.log(originalArray); // ['apple', 'banana', 'orange', 'grape', 'kiwi'] (原数组未变) // 2. 从指定索引开始到末尾 const fromIndex2 = originalArray.slice(2); console.log(fromIndex2); // ['orange', 'grape', 'kiwi'] // 3. 从指定索引开始到指定索引之前 const from1To3 = originalArray.slice(1, 4); // 包含索引1、2、3,不包含4 console.log(from1To3); // ['banana', 'orange', 'grape'] // 4. 使用负数索引 const lastTwo = originalArray.slice(-2); // 从倒数第二个开始到末尾 console.log(lastTwo); // ['grape', 'kiwi'] const middlePart = originalArray.slice(-4, -1); // 从倒数第四个开始,到倒数第一个之前 console.log(middlePart); // ['banana', 'orange', 'grape'] // 5. begin 超出长度 const emptySlice = originalArray.slice(10); console.log(emptySlice); // [] // 6. end 小于 begin const anotherEmptySlice = originalArray.slice(3, 1); console.log(anotherEmptySlice); // []
slice 和 splice 有什么区别?
我个人觉得,刚开始学JavaScript的时候,这俩名字就容易让人犯迷糊,因为它们听起来太像了。但它们的功能和对原数组的影响简直是天壤之别。
核心区别在于:slice
是“切片”,它只负责提取,然后给你一份新的副本,原数组丝毫不受影响。而 splice
则是“拼接”或者说“剪接”,它直接在原数组上动刀子,可以删除、替换或者添加元素,并且它返回的是被删除的元素(如果删除了的话)。
来看个对比:
const arr1 = ['a', 'b', 'c', 'd', 'e']; const arr2 = ['a', 'b', 'c', 'd', 'e']; // 使用 slice const slicedResult = arr1.slice(1, 4); console.log('slice 结果:', slicedResult); // slice 结果: ['b', 'c', 'd'] console.log('slice 后原数组:', arr1); // slice 后原数组: ['a', 'b', 'c', 'd', 'e'] (原数组不变) // 使用 splice const splicedResult = arr2.splice(1, 3, 'x', 'y'); // 从索引1开始删除3个元素,并插入'x', 'y' console.log('splice 结果 (被删除的元素):', splicedResult); // splice 结果 (被删除的元素): ['b', 'c', 'd'] console.log('splice 后原数组:', arr2); // splice 后原数组: ['a', 'x', 'y', 'e'] (原数组被修改了!)
你看,slice
就像是拍了张照片,原物还在;splice
则是直接改造了原物。理解这个本质区别,用起来就不会混淆了。
slice 在哪些实际场景中特别有用?
slice
方法在日常开发中有着非常广泛且实用的应用,尤其是在需要保持数据不变性(immutability)的场景下,它简直是神器。
创建数组的浅拷贝: 这是最常见的用途之一。当你需要对一个数组进行操作,但又不想影响原始数组时,
arr.slice()
(不带参数) 是最简洁的复制方式。这在函数式编程或者像 React/Redux 这样的状态管理库中尤为重要,因为它们推崇不可变数据流。const originalData = [{id: 1}, {id: 2}]; const newData = originalData.slice(); // 得到一个新数组,但内部对象仍然是引用 newData[0].id = 100; console.log(originalData[0].id); // 100 (浅拷贝的特性:内部对象还是同一个引用) // 如果要深拷贝,则需要 JSON.parse(JSON.stringify(originalData)) 或 lodash.cloneDeep
将类数组对象(Array-like Objects)转换为真正的数组: 很多时候,我们会遇到一些长得像数组但不是真正数组的对象,比如函数内部的
arguments
对象,或者 DOM 操作返回的NodeList
。它们有length
属性和索引访问,但没有Array.prototype
上的方法。slice
就能派上用场了。function sumAll() { // arguments 是一个类数组对象 const argsArray = Array.prototype.slice.call(arguments); // 或 [].slice.call(arguments) return argsArray.reduce((acc, val) => acc + val, 0); } console.log(sumAll(1, 2, 3, 4)); // 10 // 假设 document.querySelectorAll 返回一个 NodeList // const divs = document.querySelectorAll('div'); // const divArray = Array.prototype.slice.call(divs); // 现在 divArray 就可以使用所有数组方法了
这个技巧非常经典,尤其是在 ES6 普及之前,现在有了展开运算符
...
,转换起来更方便了 ([...arguments]
),但理解slice
的这种用法仍然很有价值。提取数组的子集: 比如在分页功能中,你可能需要从一个大数组中取出当前页的数据;或者在显示有限列表时,只展示前 N 项。
const allItems = Array.from({length: 100}, (_, i) => `Item ${i + 1}`); const pageSize = 10; const currentPage = 3; // 第三页 const startIndex = (currentPage - 1) * pageSize; const endIndex = startIndex + pageSize; const itemsForCurrentPage = allItems.slice(startIndex, endIndex); console.log(itemsForCurrentPage); // ['Item 21', ..., 'Item 30']
结合其他数组方法实现复杂逻辑: 你可以先
filter
一个数组,然后对结果slice
取前几项,或者先slice
一部分再map
。这种链式操作在数据处理中非常常见。
slice 处理稀疏数组或非数组对象时表现如何?
这部分内容其实蛮有意思的,它揭示了 slice
在一些“非典型”场景下的行为。
处理稀疏数组(Sparse Arrays): 稀疏数组是指那些数组中存在“空槽”的数组,比如
[1, , 3]
。当slice
遇到稀疏数组时,它会保留这些空槽。换句话说,新生成的数组在对应位置上,依然是空的(empty
)。它不会去填充这些空缺,只是原样复制。const sparseArray = [1, , 3, 4, , 6]; const slicedSparse = sparseArray.slice(1, 5); console.log(slicedSparse); // [empty, 3, 4, empty] console.log(slicedSparse.length); // 4 (长度是正确的,但中间有空洞)
这和
map
、forEach
等方法跳过空槽的行为是一致的,体现了 JavaScript 对稀疏数组的处理方式。处理非数组对象(Array-like Objects): 前面在“实际场景”中已经提到了,
slice
可以通过call
或apply
方法作用于那些拥有length
属性和索引元素的非数组对象。这种能力是slice
的一个强大特性,让它能够“借用”数组的方法。const myObject = { 0: 'hello', 1: 'world', length: 2, 2: 'extra' // 即使有额外的属性,只要 length 限制了,slice 也只看 length 范围内的 }; const newArray = Array.prototype.slice.call(myObject); console.log(newArray); // ['hello', 'world'] console.log(Array.isArray(newArray)); // true // 如果没有 length 属性,或者 length 为 0,结果就是空数组 const anotherObject = { 0: 'test' }; const emptyArray = Array.prototype.slice.call(anotherObject); console.log(emptyArray); // [] (因为没有 length 属性,或者说 length 默认为 0) const objWithNoLength = { a: 1, b: 2 }; const resultNoLength = Array.prototype.slice.call(objWithNoLength); console.log(resultNoLength); // []
这里就体现出JavaScript的灵活,但也可能让人有点困惑的地方。它不会填补那些空缺,只是原样复制。而对那些长得像数组但又不是数组的家伙,
slice
简直是它们的“变身术”,让它们瞬间拥有了数组的强大能力。这个特性在处理 DOM 集合或者自定义数据结构时非常有用。
终于介绍完啦!小伙伴们,这篇关于《JavaScript数组slice方法教程详解》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布文章相关知识,快来关注吧!

- 上一篇
- PhpStorm代码导航技巧:快速定位方法分享

- 下一篇
- ElserAIComics怎么生成动态漫画和GIF?
-
- 文章 · 前端 | 6小时前 |
- CSShover效果实用技巧分享
- 269浏览 收藏
-
- 文章 · 前端 | 6小时前 |
- npm脚本使用全攻略
- 167浏览 收藏
-
- 文章 · 前端 | 6小时前 |
- 表格列分组技巧:colgroup与col应用详解
- 143浏览 收藏
-
- 文章 · 前端 | 6小时前 |
- CSS中em是什么意思?详解em单位用法
- 498浏览 收藏
-
- 文章 · 前端 | 6小时前 |
- Vue.js防范点击劫持方法解析
- 411浏览 收藏
-
- 文章 · 前端 | 6小时前 |
- Vue.js如何防范XSS攻击?
- 385浏览 收藏
-
- 文章 · 前端 | 6小时前 |
- Vue.js性能优化技巧全解析
- 105浏览 收藏
-
- 文章 · 前端 | 6小时前 | JavaScript 安全限制 BOM 浏览器扩展 浏览器书签
- BOM如何管理浏览器书签?
- 187浏览 收藏
-
- 文章 · 前端 | 6小时前 |
- HTML标题标签从h1到h6,h1最高等级,用于主标题,h6最低,用于子标题。合理使用有助于提升网页结构和SEO优化。
- 440浏览 收藏
-
- 文章 · 前端 | 6小时前 |
- HTML下拉菜单优化与CSS过渡技巧
- 318浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 509次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 边界AI平台
- 探索AI边界平台,领先的智能AI对话、写作与画图生成工具。高效便捷,满足多样化需求。立即体验!
- 332次使用
-
- 免费AI认证证书
- 科大讯飞AI大学堂推出免费大模型工程师认证,助力您掌握AI技能,提升职场竞争力。体系化学习,实战项目,权威认证,助您成为企业级大模型应用人才。
- 359次使用
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 491次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 589次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 495次使用
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览
-
- UI设计中为何选择绝对定位的智慧之道
- 2024-02-03 501浏览