0

0

js 如何用slice获取数组的某一部分

畫卷琴夢

畫卷琴夢

发布时间:2025-08-14 10:55:01

|

1031人浏览过

|

来源于php中文网

原创

slice 方法不会修改原数组,而是返回一个新数组。1. 它通过指定起始和结束索引(不包含结束)截取原数组的一部分,支持负数索引表示从末尾开始;2. 不传参数时可实现数组的浅拷贝,即复制基本类型值和引用类型的地址;3. 与 splice 的核心区别在于 slice 是非破坏性的,splice 会直接修改原数组;4. 常用于分页、限制显示数量、创建子数组独立操作以及与其他数组方法链式调用;5. 还可用于将类数组对象转换为数组,尽管 array.from() 更推荐。这些特性使 slice 在保持数据不变性和构建清晰数据处理流程中非常实用。

js 如何用slice获取数组的某一部分

slice
方法是 JavaScript 数组的一个非常实用的工具,它能让你不改变原数组的前提下,轻松截取你需要的那一部分。简单来说,就是“切”出你想要的部分,原数组依然完整无缺。

解决方案

Array.prototype.slice()
方法返回一个从原数组中指定开始和结束位置(不包含结束位置)的浅拷贝。它不会修改原数组,这是它和
splice
最大的不同,也是我个人非常喜欢它的一个点。

它的基本语法是:

array.slice(startIndex, endIndex)

  • startIndex
    :可选。截取的起始索引(包含该索引的元素)。如果省略,默认为 0。如果是负数,则表示从数组末尾开始的偏移量。比如
    -1
    表示最后一个元素,
    -2
    表示倒数第二个。
  • endIndex
    :可选。截取的结束索引(不包含该索引的元素)。如果省略,则截取到数组末尾。如果是负数,同样表示从数组末尾开始的偏移量。

举几个例子可能更直观:

const originalArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 1. 从索引 2 开始,到索引 5 结束(不包含索引 5)
const part1 = originalArray.slice(2, 5); // 结果: [3, 4, 5]
console.log('截取 [3, 4, 5]:', part1);
console.log('原数组不变:', originalArray); // 结果: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// 2. 从索引 4 开始,一直到数组末尾
const part2 = originalArray.slice(4); // 结果: [5, 6, 7, 8, 9, 10]
console.log('截取 [5, 6, 7, 8, 9, 10]:', part2);

// 3. 使用负数索引:从倒数第 3 个元素开始,到倒数第 1 个元素结束(不包含倒数第 1 个)
const part3 = originalArray.slice(-3, -1); // 结果: [8, 9]
console.log('截取 [8, 9]:', part3);

// 4. 只用一个负数索引:从倒数第 5 个元素开始,一直到数组末尾
const part4 = originalArray.slice(-5); // 结果: [6, 7, 8, 9, 10]
console.log('截取 [6, 7, 8, 9, 10]:', part4);

// 5. 不传任何参数:实现数组的浅拷贝
const shallowCopy = originalArray.slice(); // 结果: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log('浅拷贝:', shallowCopy);

深入理解:
slice
splice
方法的核心区别是什么?

在 JavaScript 数组操作中,

slice
splice
这两个方法名字太像了,一不小心就容易混淆。但它们的核心区别在于对原数组的影响:
slice
是非破坏性的,而
splice
是破坏性的。

  • slice
    (切片)
    :正如我们上面讲的,它就像切面包一样,从原面包上切下一片,原面包还在,你拿到的是新切下来的那一片。它返回一个新的数组,包含你“切”出来的元素,原数组保持不变。这对于需要保持数据完整性,或者在不影响原始数据的情况下进行操作的场景非常重要。
  • splice
    (拼接/剪接)
    :这个方法就比较“暴力”了,它直接在原数组上进行操作,可以删除、替换或添加元素。一旦你用了
    splice
    ,原数组可能就面目全非了。它返回一个包含被删除元素的数组(如果没有删除元素则返回空数组),但重点是,原数组被修改了。

来看个对比:

const arr1 = [1, 2, 3, 4, 5];
const arr2 = [1, 2, 3, 4, 5];

// 使用 slice
const slicedArr = arr1.slice(1, 3);
console.log('slice 后的新数组:', slicedArr); // [2, 3]
console.log('slice 后的原数组:', arr1);     // [1, 2, 3, 4, 5] (不变)

// 使用 splice
const splicedArr = arr2.splice(1, 3); // 从索引 1 开始删除 3 个元素
console.log('splice 返回的被删除元素:', splicedArr); // [2, 3, 4]
console.log('splice 后的原数组:', arr2);     // [1, 5] (被修改了)

所以,当你只需要获取数组的一部分,且不希望改变原始数据时,毫不犹豫地选择

slice
。如果你需要修改原数组,比如删除或插入元素,那
splice
才是你的工具。

slice
如何实现数组的浅拷贝?在哪些场景下会用到?

slice
方法在不传入任何参数时,会返回原数组的一个浅拷贝。这意味着它会创建一个新数组,并将原数组的所有元素(如果元素是基本类型,则直接复制值;如果元素是引用类型,则复制引用地址)复制到新数组中。

const originalArr = [1, { name: 'Alice' }, [10, 20]];
const shallowCopyArr = originalArr.slice();

console.log(shallowCopyArr); // [1, { name: 'Alice' }, [10, 20]]
console.log(originalArr === shallowCopyArr); // false (是不同的数组对象)

// 验证浅拷贝:修改基本类型不影响原数组
shallowCopyArr[0] = 99;
console.log(originalArr[0]); // 1 (原数组未变)

// 验证浅拷贝:修改引用类型会影响原数组
shallowCopyArr[1].name = 'Bob';
console.log(originalArr[1].name); // Bob (原数组的引用对象被修改了)

shallowCopyArr[2][0] = 100;
console.log(originalArr[2][0]); // 100 (原数组的引用对象被修改了)

使用场景:

  1. 避免副作用:当你需要对一个数组进行操作(比如排序、过滤),但又不想影响到原始数据时,可以先用
    slice()
    创建一个副本,然后在副本上进行操作。这在函数式编程中非常常见,有助于保持数据的不可变性。
    const users = [{ id: 3, name: 'C' }, { id: 1, name: 'A' }, { id: 2, name: 'B' }];
    const sortedUsers = users.slice().sort((a, b) => a.id - b.id);
    console.log('排序后的新数组:', sortedUsers);
    console.log('原数组 (未变):', users);
  2. 转换类数组对象:在一些旧的浏览器环境或者特定场景下,你可能会遇到一些“类数组对象”(比如
    arguments
    对象,或者 DOM 的
    NodeList
    ),它们有
    length
    属性和索引访问,但没有数组的
    forEach
    map
    等方法。这时候,
    slice.call()
    是一种很经典的转换方式。
    // 假设这是一个函数内部的 arguments 对象
    function logArguments() {
        // arguments 是一个类数组对象
        // const argsArray = Array.prototype.slice.call(arguments); // 经典用法
        const argsArray = Array.from(arguments); // ES6 更推荐的写法
        console.log(argsArray);
        console.log(Array.isArray(argsArray)); // true
    }
    logArguments('hello', 123, true); // 输出: ["hello", 123, true]

    虽然现在

    Array.from()
    可能是更简洁和推荐的做法,但了解
    slice.call()
    这种老牌用法也很有意思,能让你理解更多 JavaScript 的底层机制。

    j2me3D游戏开发简单教程 中文WORD版
    j2me3D游戏开发简单教程 中文WORD版

    本文档主要讲述的是j2me3D游戏开发简单教程; 如今,3D图形几乎是任何一部游戏的关键部分,甚至一些应用程序也通过用3D形式来描述信息而获得了成功。如前文中所述,以立即模式和手工编码建立所有的3D对象的方式进行开发速度很慢且很复杂。应用程序中多边形的所有角点必须在数组中独立编码。在JSR 184中,这称为立即模式。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

    下载

除了截取和浅拷贝,
slice
在实际项目中还有哪些巧妙的应用?

slice
作为一个看似简单的数组方法,在实际开发中其实有不少非常实用的“小技巧”和应用场景,远不止于简单的截取。

  1. 实现分页逻辑:这是最常见的应用之一。当你从后端获取大量数据,需要在前端进行分页展示时,

    slice
    可以轻松地帮你取出当前页的数据。

    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(`第 ${currentPage} 页的数据:`, itemsForCurrentPage);
    // 结果: ["Item 21", "Item 22", ..., "Item 30"]

    这种方式非常直观,而且性能也不错,因为它只是创建了一个小范围的新数组。

  2. 截断数组以限制显示数量:在 UI 界面中,我们经常需要展示列表的一部分,比如“最新评论”只显示前 5 条,或者“热门标签”只显示前 10 个。

    const comments = ['评论1', '评论2', '评论3', '评论4', '评论5', '评论6'];
    const displayComments = comments.slice(0, 3); // 只显示前 3 条
    console.log('显示评论:', displayComments); // ["评论1", "评论2", "评论3"]

    这比手动循环或者用

    for
    循环控制要简洁很多。

  3. 创建子数组进行独立操作:有时候你需要对数组的某个特定部分进行一系列复杂操作,但又不希望这些操作影响到原数组的其他部分。你可以先

    slice
    出一个子数组,然后在子数组上随意折腾。

    const dataSet = [10, 20, 30, 40, 50, 60, 70];
    // 假设我们只想处理中间的一部分数据
    const middlePart = dataSet.slice(2, 5); // [30, 40, 50]
    
    const processedMiddlePart = middlePart.map(num => num * 2).filter(num => num > 70);
    console.log('处理后的中间部分:', processedMiddlePart); // [80, 100]
    console.log('原数据集:', dataSet); // [10, 20, 30, 40, 50, 60, 70] (未变)

    这种模式有助于代码的模块化和清晰度,每个操作都在它自己的数据副本上进行,减少了潜在的副作用。

  4. 结合其他数组方法进行链式操作:因为

    slice
    返回一个新数组,你可以很自然地将它与其他数组方法(如
    map
    ,
    filter
    ,
    reduce
    ,
    sort
    等)进行链式调用,构建出非常强大且可读性高的操作流。

    const products = [
      { id: 1, name: 'Laptop', price: 1200 },
      { id: 2, name: 'Mouse', price: 25 },
      { id: 3, name: 'Keyboard', price: 75 },
      { id: 4, name: 'Monitor', price: 300 },
      { id: 5, name: 'Webcam', price: 50 }
    ];
    
    // 获取价格在 50 到 300 之间(不含 300)的商品,并按价格从低到高排序,只取前 2 个
    const filteredAndSortedTop2 = products
      .filter(p => p.price >= 50 && p.price < 300) // 过滤出符合条件的
      .sort((a, b) => a.price - b.price)         // 排序
      .slice(0, 2);                               // 只取前 2 个
    
    console.log('筛选排序后的前2个商品:', filteredAndSortedTop2);
    // 结果: [{ id: 5, name: 'Webcam', price: 50 }, { id: 3, name: 'Keyboard', price: 75 }]

    这种链式调用让数据处理逻辑变得非常流畅和富有表现力,是我在日常开发中经常会用到的模式。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

395

2023.09.04

php中foreach用法
php中foreach用法

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

75

2025.12.04

length函数用法
length函数用法

length函数用于返回指定字符串的字符数或字节数。可以用于计算字符串的长度,以便在查询和处理字符串数据时进行操作和判断。 需要注意的是length函数计算的是字符串的字符数,而不是字节数。对于多字节字符集,一个字符可能由多个字节组成。因此,length函数在计算字符串长度时会将多字节字符作为一个字符来计算。更多关于length函数的用法,大家可以阅读本专题下面的文章。

928

2023.09.19

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

46

2025.09.03

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

75

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

36

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

61

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

42

2025.11.27

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

0

2026.01.30

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何进行WebSocket调试
如何进行WebSocket调试

共1课时 | 0.1万人学习

TypeScript全面解读课程
TypeScript全面解读课程

共26课时 | 5.1万人学习

前端工程化(ES6模块化和webpack打包)
前端工程化(ES6模块化和webpack打包)

共24课时 | 5.1万人学习

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

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