0

0

JavaScript的Array.prototype.slice方法是什么?怎么用?

幻夢星雲

幻夢星雲

发布时间:2025-07-08 14:57:01

|

223人浏览过

|

来源于php中文网

原创

javascript的array.prototype.slice方法用于从现有数组中提取指定索引范围的元素并生成新数组,且不会修改原数组。1. 它接受两个可选参数begin和end,begin指定开始索引(默认为0,负数表示从末尾倒数),end指定结束索引(不包含该索引元素,默认为数组末尾);2. 返回一个包含提取元素的新数组,原数组保持不变;3. 常用于数组复制、子集提取、类数组对象转换等场景;4. 在处理稀疏数组时保留空槽,在处理非数组对象时可通过call或apply将其转换为数组。

JavaScript的Array.prototype.slice方法是什么?怎么用?

JavaScript的Array.prototype.slice方法,简单来说,就是一个用来从现有数组中“切”出一段内容,然后生成一个全新的数组的方法。它不会改变原始数组,这很重要。

JavaScript的Array.prototype.slice方法是什么?怎么用?

解决方案

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

这个方法的语法是 arr.slice([begin[, end]])

立即学习Java免费学习笔记(深入)”;

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

slice 方法返回一个包含提取元素的新数组。

看几个例子可能更直观:

JavaScript的Array.prototype.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 则是直接改造了原物。理解这个本质区别,用起来就不会混淆了。

Favird
Favird

极其棒且有价值的互联网资源目录!

下载

slice 在哪些实际场景中特别有用?

slice 方法在日常开发中有着非常广泛且实用的应用,尤其是在需要保持数据不变性(immutability)的场景下,它简直是神器。

  1. 创建数组的浅拷贝: 这是最常见的用途之一。当你需要对一个数组进行操作,但又不想影响原始数组时,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
  2. 将类数组对象(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 的这种用法仍然很有价值。

  3. 提取数组的子集: 比如在分页功能中,你可能需要从一个大数组中取出当前页的数据;或者在显示有限列表时,只展示前 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']
  4. 结合其他数组方法实现复杂逻辑: 你可以先 filter 一个数组,然后对结果 slice 取前几项,或者先 slice 一部分再 map。这种链式操作在数据处理中非常常见。

slice 处理稀疏数组或非数组对象时表现如何?

这部分内容其实蛮有意思的,它揭示了 slice 在一些“非典型”场景下的行为。

  1. 处理稀疏数组(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 (长度是正确的,但中间有空洞)

    这和 mapforEach 等方法跳过空槽的行为是一致的,体现了 JavaScript 对稀疏数组的处理方式。

  2. 处理非数组对象(Array-like Objects): 前面在“实际场景”中已经提到了,slice 可以通过 callapply 方法作用于那些拥有 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 集合或者自定义数据结构时非常有用。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
es6新特性
es6新特性

es6新特性有:1、块级作用域变量;2、箭头函数;3、模板字符串;4、解构赋值;5、默认参数;6、 扩展运算符;7、 类和继承;8、Promise。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

106

2023.07.17

es6新特性有哪些
es6新特性有哪些

es6的新特性有:1、块级作用域;2、箭头函数;3、解构赋值;4、默认参数;5、扩展运算符;6、模板字符串;7、类和模块;8、迭代器和生成器;9、Promise对象;10、模块化导入和导出等等。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.08.04

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

233

2025.12.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1567

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

241

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

150

2025.10.17

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

267

2025.12.04

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

549

2023.12.01

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
JavaScript 基础加强视频教程
JavaScript 基础加强视频教程

共73课时 | 17.5万人学习

Git工具使用小知识
Git工具使用小知识

共38课时 | 17.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号