ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

千古前端教程:数组常见操作实战指南——从接口数据到列表渲染的完整处理方案

2026/10/3 2:04:17 拓冰建站 浏览量
千古前端教程:数组常见操作实战指南——从接口数据到列表渲染的完整处理方案 文档教程前端【免费下载链接】Web千古前端图文教程超详细的前端入门到进阶知识库。从零开始学前端做一名精致优雅的前端工程师。项目地址https://gitcode.com/gh_mirrors/we/Web点击查看免费下载导读前端同学通过接口拿到 JSON 数据后往往需要把数据进行各种形式的变换和展示——提取字段、过滤筛选、排序、去重、合并、拆分这些操作都建立在数组的常见方法之上。本文以千古前端图文教程中的《数组的常见操作》一文为核心系统梳理实战开发中最高频的数组操作方案从「从对象数组中提取属性值为新数组」这一最常用场景出发深入讲解 map、forEach、filter、sort、splice、reduce 等方法的正确用法、返回值与副作用并给出可直接复制运行的完整代码示例。读完本文你将能熟练完成接口数据到列表渲染、筛选排序、字段重组等绝大多数日常开发任务。若对数组的基础知识创建、索引、length 属性、遍历尚不熟悉建议先阅读仓库中的 04-JavaScript基础/18-数组简介.md 打牢基础再回到本文学习实战操作。一、为什么实战开发离不开数组操作数组在实战开发中使用得相当频繁。前后端分离的开发模式下前端通过接口拿到的数据大多是 JSON 数组例如[ { id: 1, name: 奔驰, ctime: 2024-01-01 }, { id: 2, name: 大众, ctime: 2024-01-02 } ]拿到这样的数据后前端往往需要提取某个字段用于下拉选项、按时间排序、筛选出满足条件的项、统计总和、去重、拼接成字符串等。数组的常见操作就发挥了很大的作用。仓库中 12-Vue基础/05-Vue的举例列表功能.md 展示的就是典型的「接口数组数据 → v-for 渲染列表」场景其中list就是一个对象数组页面上展示的是item.id、item.name、item.ctime这些字段——这正是数组操作的前提与落点。二、核心操作从对象数组中提取属性的值这是原文档重点讲解、也是实战中出现频率最高的操作。例如商品列表接口返回了包含skuId、name的对象数组现在需要把所有的skuId提取成一个新数组用于批量操作或回显。一般人的做法是用 for 循环遍历后逐个 push但这种做法不够简洁// 不够简洁的写法 const arr1 [ { skuId: 123, name: 商品1 }, { skuId: 456, name: 商品2 }, { skuId: 789, name: 商品3 } ]; const skuIdArr []; for (let i 0; i arr1.length; i) { skuIdArr.push(arr1[i].skuId); }最佳答案使用map()方法一行搞定const arr1 [ { skuId: 123, name: 商品1 }, { skuId: 456, name: 商品2 }, { skuId: 789, name: 商品3 } ]; // 将数组 arr1 中的 skuId 字段提取为一个新的数组 const skuIdArr arr1.map(item item.skuId); console.log(JSON.stringify(skuIdArr));打印结果[123,456,789]map() 的原理与注意事项map()会对数组中的每一项运行回调函数返回该函数的结果组成加工后的新数组不会改变原数组。其回调函数可接收三个参数currentItem当前元素、currentIndex当前索引、currentArray原数组。基于此可以派生出更复杂的字段重组这在仓库 04-JavaScript基础/19-数组的常见方法.md 中有完整说明。例如把name、age两个字段改名后输出const arr1 [ { name: 千古壹号, age: 28 }, { name: 许嵩, age: 32 }, ]; // 提取 name 属性 const arr2 arr1.map(item item.name); // 改写属性名注意箭头函数返回对象时要加小括号包裹 const arr3 arr1.map(item ({ myName: item.name, myAge: item.age, })); console.log(arr2: JSON.stringify(arr2)); // arr2:[千古壹号,许嵩] console.log(arr3: JSON.stringify(arr3)); // arr3:[{myName:千古壹号,myAge:28},{myName:许嵩,myAge:32}]需要特别警惕两个 map() 的坑map() 方法会不会改变原数组答案是不一定。如果回调中修改的是整个item的引用不会改变原数组但如果是修改item里面的某个属性如item.name haha则会改变原数组。因此如果你只是想修改对象中的某个属性值、不想创建新数组建议改用forEach()。map() 回调中不写 return 会怎样不会报错但该元素会被映射为undefined最终得到[undefined, undefined, ...]。map() 的设计初衷是创建新数组务必记得 return。三、遍历数组for、forEach 与 for of遍历是数组操作的基础。仓库 04-JavaScript基础/19-数组的常见方法.md 中介绍了三种主流遍历方式1. for 循环最传统兼容性最好IE8 及以下环境必须使用它const arr [千古壹号, 许嵩, vae]; for (let i 0; i arr.length; i) { console.log(arr[i]); }2. forEach()ES5 方法支持 IE8 以上浏览器let myArr [王一, 王二, 王三]; myArr.forEach((currentItem, currentIndex, currentArray) { console.log(item: currentItem); // 当前元素 console.log(index: currentIndex); // 当前索引 console.log(arr: JSON.stringify(currentArray)); // 原数组 });注意forEach() 没有返回值返回值为 undefined不能用newArray arr.forEach(...)的方式接收结果。此外forEach 是否改变原数组取决于操作方式基本数据类型直接赋值无效打印结果仍是原数组引用数据类型修改元素对象里的属性则会影响原数组。标准做法是利用回调的第二个、第三个参数arr[index] ...来修改原数组。3. for ofES6 语法直接取元素值const arr [a, b, c]; for (let value of arr) { console.log(value); }注意不要用 for in 遍历数组。for in 是专门用于遍历对象的对象的属性是无序的而数组元素有顺序用 for in 遍历数组容易踩坑。四、过滤数组filter()filter()对数组中每一项运行回调函数返回结果是 true 的项组成新数组不会改变原数组。这是「从接口数据中筛选符合条件的记录」的核心手段。举例 1找出数组中大于 4 的元素let arr1 [1, 3, 6, 2, 5, 6]; let arr2 arr1.filter(item item 4); // 简洁写法 console.log(JSON.stringify(arr2)); // 打印结果[6,5,6]举例 2从对象数组中筛选指定类型实战最常用如筛选一线歌手、筛选某个状态下的订单const arr1 [ { name: 许嵩, type: 一线 }, { name: 周杰伦, type: 退居二线 }, { name: 邓紫棋, type: 一线 }, ]; const arr2 arr1.filter(item item.type 一线); console.log(JSON.stringify(arr2)); // [{name:许嵩,type:一线},{name:邓紫棋,type:一线}]常见误区如果return语句位于回调函数第一行后面的代码将永远不执行。例如return item.num 1; arr2.push(item);中push永远不会被调用只有把 return 放进if条件内才能让部分元素继续走到 push。写代码时要注意 return 的位置。五、排序sort() 及其在对象数组上的应用sort()会改变原数组。不带参数时默认按照元素的 Unicode 编码从小到大排序这会导致数字排序出现意外——例如[5, 2, 11, 3, 4, 1].sort()的结果是[1, 11, 2, 3, 4, 5]因为11的编码小于2。所以数字排序必须带参自定义排序规则。JS 根据回调函数的返回值决定排序返回大于 0 的值则交换位置返回小于 0 的值不交换返回 0 则视为相等不交换。因此最简洁的写法是let arr [5, 2, 11, 3, 4, 1]; let result arr.sort((a, b) a - b); // 升序排列推荐写法 // arr.sort((a, b) b - a); // 降序排列实战对象数组按字段排序实际开发中列表数据往往需要按某个字段如发布时间排序。完整代码如下!DOCTYPE html html langen head meta charsetUTF-8 / titleDocument/title /head body script let dataList [ { title: 品牌鞋子高品质低价入手, publishTime: 200 }, { title: 不是很贵但是很暖, publishTime: 100 }, { title: 无法拒绝的美食跟我一起吃, publishTime: 300 }, ]; console.log(排序前的数组 JSON.stringify(dataList)); // 将 dataList 数组按照 publishTime 字段从小到大排序会改变原数组 dataList.sort((a, b) parseInt(a.publishTime) - parseInt(b.publishTime)); console.log(排序后的数组 JSON.stringify(dataList)); /script /body /html打印结果中publishTime为 100、200、300 的三条数据按时间顺序排列。为什么排序前还要做一次parseInt()因为这类字段由后台接口返回可能是 int 类型、也可能是字符串类型前端统一先做parseInt()转换比较保险这是一种良好的工作习惯和风险意识。六、删除数组元素splice() 与 delete 的本质区别「遍历数组的同时删除数组中的所有元素」是面试与实战中的高频需求。仓库 07-JavaScript进阶/数组的进阶操作.md 专门讲解了两种删除方式的差异使用 splice() 删除后数组长度会变化使用 delete 删除后数组长度不变。写法 1错误正序遍历 splice()let arr [1, 2, 3, 4, 5]; for (let i 0; i arr.length; i) { arr.splice(i, 1); } console.log(arr); // 最终值[2, 4]错误原因splice 会使数组长度不断变化每删除一个元素后续元素自动补位导致跳过了部分元素。写法 2错误固定长度 splice()let arr [1, 2, 3, 4, 5]; const len arr.length; for (let i 0; i len; i) { arr.splice(i, 1); } console.log(arr); // 最终值依然是 [2, 4]写法 3正确从末尾开始删除let arr [1, 2, 3, 4, 5]; for (let i arr.length - 1; i 0; i--) { arr.splice(i, 1); } console.log(arr); // 最终值[] console.log(arr.length); // 最终长度0写法 4使用 delete 关键字长度不变let arr [1, 2, 3, 4, 5]; for (let i 0; i arr.length; i) { // 注意通过 delete 删除数组中的元素数组的长度不会发生变化 delete arr[i]; } console.log(JSON.stringify(arr)); // [null, null, null, null, null]长度仍为 5删除指定元素实战最常用const arr4 [a, b, c, d]; arr4.splice(arr4.indexOf(c), 1); // 删除数组中的 c 这个元素 console.log(JSON.stringify(arr4)); // [a,b,d]splice()的完整语法为数组.splice(起始索引index, 需要删除的个数, 新的元素1, 新的元素2...)第三个及之后的参数表示删除元素后向原数组补充的新内容。它还常被用来批量替换例如将[a, b, c, d]中索引 1、2 的值改为 e、farr.splice(1, 2, e, f)。七、查找元素indexOf、find、findIndex 与 includesindexOf() / lastIndexOf()indexOf()从左往右查找元素第一次出现的索引找到立即停止lastIndexOf()从右往左查找找不到都返回 -1。检索时是严格类型约束类似所以[1,2,3].indexOf(2)返回 -1。该方法支持第二个参数指定查找的起始位置这在数据结构与算法面试题中时常出现let arr [q, i, a, n, g, u, y, i, h, a, o]; let result arr.indexOf(a, 3); // 从下标为 3 的位置开始查找 a console.log(result); // 打印结果9find() 与 findIndex()find()找出第一个满足条件回调返回 true的元素并立即停止查找找不到返回 undefinedfindIndex()返回该元素的索引找不到返回 -1。注意如果通过 find 返回的itemResult修改了其内部属性原数组对应元素也会被改变引用类型共享let arr [2, 3, 2, 5, 7, 6]; let result arr.find((item, index) { return item 4; // 一旦发现第一个大于 4 的元素就返回 }); console.log(result); // 打印结果5 let indexResult arr.findIndex(item item 4); console.log(indexResult); // 打印结果3includes()判断数组中是否包含指定元素返回布尔值第二个参数position可规定检索起始位置默认为 0const arr [11, 12, 13, 14, 15]; console.log(arr.includes(12)); // true console.log(arr.includes(20)); // false console.log(arr.includes(11, 1)); // false从下标 1 开始找 11every() 与 some()every()全真才为真要求每一项都返回 true最终才返回 truesome()一真即真只要有一项返回 true 就停止遍历并返回 true。记法every 全真才真some 点到为止。八、合并与复制concat、扩展运算符与 sliceconcat()连接多个数组并返回新数组不改变原数组slice()从数组中提取指定区间元素组成新数组包左不包右也不会改变原数组。二者都不会修改原数组与 splice() 形成鲜明对比const arr1 [1, 2, 3]; const arr2 [a, b, c]; const result arr1.concat(arr2); // [1, 2, 3, a, b, c] const arr [a, b, c, d, e, f]; const result2 arr.slice(2, 4); // [c, d]包含开始不包含结束ES6 扩展运算符是更简洁的合并方式同时还能实现数组的浅拷贝——这是避免「赋值共享内存地址」bug 的关键。详见仓库 05-JavaScript基础ES6语法/07-剩余参数和扩展运算符.md// 合并数组 const arr3 [...arr1, ...arr2]; // [a,b,c,1,2,3] 风格的结果 arr1.push(...arr2); // 直接在原数组末尾追加 // 浅拷贝数组重新开辟内存地址与原数组互不影响 let arrA [www, smyhvae, com]; let arrB [...arrA]; // arrB 与 arrA 不再指向同一地址 arrB.push(你懂得); console.log(arrA); // [www,smyhvae,com]不受影响注意数组不能使用加号拼接使用加号会先转换成字符串再拼接如[1,2] [3,4]得到1,23,4。九、数组与字符串互转join() 与 split()join()将数组转为字符串可指定连接符不传参时默认使用英文逗号此时与toString()效果一致split() 是字符串的方法不是数组的方法通过指定分隔符把字符串拆分为数组。这两个方法一正一反配合起来常用于展示与传输const arr [a, b, c]; const result1 arr.join(); // a,b,c默认逗号连接 const result2 arr.join(-); // a-b-c const str q,i,a,n; const arr2 str.split(,); // [q,i,a,n]实战场景接口返回类似q,i,a,n的字符串时用split(,)拆成数组再渲染反过来把多选数组用join(|)拼成参数传给后端。仓库 04-JavaScript基础/19-数组的常见方法.md 还给出了一道经典练习将字符串数组输出为|分割的形式如千古|宿敌|素颜推荐直接用arr.join(|)而非 for 循环手动拼接——因为字符串具有不变性频繁拼接容易造成内存压力。十、伪数组转真数组Array.from() 与扩展运算符通过document.getElementsByTagName(button)、document.getElementsByClassName(div)等方式获取的 DOM 集合以及函数内部的arguments都是伪数组它们包含 length 属性、可迭代但原型链中没有Array.prototype因此无法直接使用pop()、join()等数组方法。转换方式有两种// 方式1ES6 的 Array.from()推荐 const btnArray document.getElementsByTagName(button); const realArray Array.from(btnArray); // 方式2扩展运算符 const divArr [...document.getElementsByClassName(div)];Array.from()与new Array()的区别在于Array.of(1, abc, true)创建的是内容为[1, abc, true]的数组而new Array(4)创建的是长度为 4 的空数组。相关内容可继续阅读仓库 05-JavaScript基础ES6语法/08-字符串、数组、对象的扩展.md。十一、高阶操作reduce() 的三大实战应用reduce()接收一个函数作为累加器从左到右处理数组中的每个值最终计算为一个值。回调参数依次为previousValue上一次回调的返回值必填、currentValue当前元素必填、currentIndex选填、arr选填还可以传入initialValue作为第一次调用时的初始值。它是替代很多数组方法的进阶利器三个典型应用如下1. 求和const arr [2, 0, 1, 9, 6]; const total arr.reduce((prev, item) { return prev item; }); console.log(total: total); // 打印结果182. 统计某个元素出现的次数function repeatCount(arr, value) { if (!arr || arr.length 0) return 0; return arr.reduce((totalCount, item) { totalCount item value ? 1 : 0; return totalCount; }, 0); } let arr1 [1, 2, 6, 5, 6, 1, 6]; console.log(repeatCount(arr1, 6)); // 打印结果33. 求最大值const arr [2, 0, 1, 9, 6]; const maxValue arr.reduce((prev, item) { return prev item ? prev : item; }); console.log(maxValue); // 打印结果9十二、综合实战从接口数据到列表展示的完整链路把本文的操作串起来就是一条典型的「接口数据 → 变换 → 展示」链路可对照 12-Vue基础/05-Vue的举例列表功能.md 中的列表渲染代码理解落点// 1. 假设接口返回的商品数据 const rawList [ { skuId: 123, name: 商品1, price: 199, status: 1, publishTime: 2024-03-01 }, { skuId: 456, name: 商品2, price: 299, status: 0, publishTime: 2024-02-01 }, { skuId: 789, name: 商品3, price: 99, status: 1, publishTime: 2024-01-01 }, ]; // 2. 提取 skuId 列表对应原文档的核心操作 const skuIdArr rawList.map(item item.skuId); // [123,456,789] // 3. 筛选出 status 为 1在售的商品 const onSaleList rawList.filter(item item.status 1); // 4. 按发布时间从新到旧排序统一 parseInt 防御字符串字段 onSaleList.sort((a, b) parseInt(b.publishTime.replace(/-/g, )) - parseInt(a.publishTime.replace(/-/g, ))); // 5. 计算在售商品的价格总和 const totalPrice onSaleList.reduce((prev, item) prev parseInt(item.price), 0); // 6. 把 skuId 数组拼接成字符串传给后端 const skuIdStr skuIdArr.join(,);结语与延伸阅读本文围绕「从对象数组中提取属性值」这一核心操作展开系统覆盖了遍历、过滤、排序、删除、查找、合并、转换、累加等实战高频场景全部代码均可直接复制运行验证。实战中请记住几个关键结论提取字段用map()、筛选用filter()、按字段排序用带回调的sort()、删除指定元素用splice(indexOf(x), 1)、遍历删除要从末尾开始、伪数组用Array.from()或扩展运算符转换、字符串与数组互转用split()与join()。想继续深入推荐阅读仓库中的以下文档04-JavaScript基础/19-数组的常见方法.md数组方法的完整清单与逐个详解含 fill、reverse、valueOf 等07-JavaScript进阶/数组的进阶操作.md遍历删除数组元素的正确写法与 delete 的差异05-JavaScript基础ES6语法/07-剩余参数和扩展运算符.md扩展运算符合并、拷贝数组的底层原理05-JavaScript基础ES6语法/08-字符串、数组、对象的扩展.mdArray.from、find、findIndex 等 ES6 扩展04-JavaScript基础/18-数组简介.md数组的创建、索引、length 属性与稀疏数组等基础概念赞分享文档教程前端【免费下载链接】Web千古前端图文教程超详细的前端入门到进阶知识库。从零开始学前端做一名精致优雅的前端工程师。项目地址https://gitcode.com/gh_mirrors/we/Web点击查看免费下载相关推荐千古前端图文教程Vue 列表功能实战——从 v-for 数据渲染到增删查改完整实现千古前端图文教程Vue 列表功能实战——从 v for 数据渲染到增删查改完整实现 本文选自千古前端图文教程GitHub 加速计划 / we / Web 仓文档教程前端千古前端数据库基础MySQL安装、操作和常用命令的完整指南千古前端数据库基础MySQL安装、操作和常用命令的完整指南 MySQL是前端开发中常用的关系型数据库掌握其基础操作对构建动态网站和管理数据至关重要。本指南将文档教程前端千古前端教程Node.js 操作 MySQL 数据库连接、增删改查全流程实战千古前端教程Node.js 操作 MySQL 数据库连接、增删改查全流程实战 导读 本篇文章出自《千古前端图文教程》的 Node.js 系列讲解如何用文档教程前端上一篇深入理解klipper_z_calibration工作原理从代码到实践下一篇RePKG技术解密掌握Wallpaper Engine资源处理的终极武器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考