JavaScript | 数组方法实战教程:push()、forEach()、filter()、sort()

JavaScript 数组方法实战教程:push()、forEach()、filter()、sort()

你是否在处理 JavaScript 数组数据时,不知道该用哪个方法添加元素、遍历数据、筛选内容或排序?这篇教程将通过具体场景、可运行代码,以及常见错误与解决方案,帮你彻底掌握 push()forEach()filter()sort() 四个核心数组方法的功能与实际用法,学完就能直接在项目中落地。

一、push():给数组"尾部追加"元素

核心功能

push() 方法用于向数组的末尾添加一个或多个元素,并且会返回更新后数组的长度(注意:不是更新后的数组本身)。它会直接修改原始数组,这是一个重要特性。

适用场景

  • 向列表中追加新数据(如用户提交表单后,将新用户信息加入用户列表)
  • 批量补充数据到数组尾部
  • 动态构建数组(逐步添加元素)

可运行代码案例

javascript 复制代码
// 1. 基础用法:添加单个元素
const fruitList = ['苹果', '香蕉', '橙子'];
// 调用push(),添加单个元素
const newLength1 = fruitList.push('葡萄');
console.log('添加单个元素后的数据:', fruitList); // 输出:['苹果', '香蕉', '橙子', '葡萄']
console.log('更新后数组长度:', newLength1); // 输出:4

// 2. 进阶用法:添加多个元素
const numberArr = [1, 2, 3];
// 调用push(),批量添加多个元素(用逗号分隔)
const newLength2 = numberArr.push(4, 5, 6);
console.log('添加多个元素后的数据:', numberArr); // 输出:[1, 2, 3, 4, 5, 6]
console.log('更新后数组长度:', newLength2); // 输出:6

// 3. 实战场景:用户列表追加新用户
const userList = [
  { id: 1, name: '张三', age: 25 },
  { id: 2, name: '李四', age: 28 }
];
// 新用户数据
const newUser = { id: 3, name: '王五', age: 30 };
// 追加新用户
userList.push(newUser);
console.log('追加新用户后的列表:', userList);
// 输出:[{ id:1, ... }, { id:2, ... }, { id:3, ... }]

常见错误与解决方案

常见错误 错误描述 解决方案
错误1:误将push()返回值当作更新后的数组 代码示例:const newArr = fruitList.push('葡萄');,此时newArr是数字4(数组长度),而非数组本身,导致后续操作报错 1. 先调用push()修改原始数组;2. 若需保留原数组,先复制原数组(const newArr = [...fruitList]),再对复制后的数组调用push();3. 避免直接接收push()的返回值作为数组使用
错误2:给非数组类型调用push() 代码示例:const str = 'abc'; str.push('d');,字符串不是数组,没有push()方法,报错Uncaught TypeError: str.push is not a function 1. 先确认目标变量是数组类型(可用Array.isArray(obj)判断);2. 若为类数组/字符串,先转换为数组(字符串转数组:Array.from(str),类数组转数组:[...arguments]
错误3:批量添加数组时,直接传入数组导致二维数组 代码示例:const arr = [1,2]; arr.push([3,4]);,结果为[1,2,[3,4]](非预期的[1,2,3,4] 1. 使用扩展运算符:arr.push(...[3,4]),将数组展开为单个元素后追加;2. 也可使用concat()方法(const newArr = arr.concat([3,4]),不修改原数组)

二、forEach():遍历数组的"万能工具"

核心功能

forEach() 方法用于遍历数组的每一个元素 ,并对每个元素执行你指定的回调函数。它没有返回值(返回 undefined),仅用于执行遍历操作,可选择性地修改原始数组(取决于回调函数内的操作)。

适用场景

  • 遍历数组并打印/展示所有元素
  • 对数组中每个元素执行统一操作(如格式化数据、累加计算)
  • 无需返回新数组,仅需遍历处理的场景

可运行代码案例

javascript 复制代码
// 1. 基础用法:遍历数组并打印每个元素
const animalArr = ['老虎', '大象', '熊猫', '猴子'];
console.log('动物列表遍历结果:');
animalArr.forEach((animal, index) => {
  // 回调函数参数:item(当前元素)、index(当前索引,可选)、array(原数组,可选)
  console.log(`索引${index}:${animal}`);
});
// 输出:
// 索引0:老虎
// 索引1:大象
// 索引2:熊猫
// 索引3:猴子

// 2. 进阶用法:遍历数组并累加计算
const scoreArr = [85, 92, 78, 90, 88];
let totalScore = 0;
// 遍历分数数组,累加总分
scoreArr.forEach(score => {
  totalScore += score;
});
const averageScore = totalScore / scoreArr.length;
console.log('总分:', totalScore); // 输出:431
console.log('平均分:', averageScore); // 输出:86.2

// 3. 实战场景:格式化数组元素(给商品名称添加前缀)
const productList = ['手机', '电脑', '平板', '耳机'];
const formatProductList = [];
// 遍历商品列表,格式化后存入新数组
productList.forEach(product => {
  formatProductList.push(`热销-${product}`);
});
console.log('格式化后的商品列表:', formatProductList);
// 输出:['热销-手机', '热销-电脑', '热销-平板', '热销-耳机']

常见错误与解决方案

常见错误 错误描述 解决方案
错误1:试图用return终止forEach()遍历 代码示例:animalArr.forEach(animal => { if (animal === '熊猫') return; console.log(animal); })return仅跳过当前循环,无法终止整个遍历,仍会打印"猴子" 1. 若需终止遍历,放弃forEach(),使用for循环/for...of循环(可通过break终止);2. 若仅需跳过部分元素,return可正常使用
错误2:误将forEach()当作有返回值的方法 代码示例:const newArr = productList.forEach(p => 热销-${p});newArr值为undefined,非预期数组 1. 先创建空数组,在forEach()回调内用push()存入处理后的数据(如案例3);2. 直接使用map()方法(专门用于返回处理后的新数组,更简洁)
错误3:遍历中修改数组长度导致遍历不完整/死循环 代码示例:const arr = [1,2,3]; arr.forEach(item => { arr.push(item * 2); }),会无限追加元素导致死循环;若删除元素则会跳过部分元素 1. 遍历前先复制数组([...arr]),遍历复制后的数组,修改原始数组;2. 避免在forEach()中直接增删原始数组的元素,防止破坏遍历结构
错误4:回调函数中使用this指向丢失(普通函数写法) 代码示例:const obj = { num: 10 }; arr.forEach(function(item) { console.log(this.num); }),此时this指向window(非严格模式),输出undefined 1. 使用箭头函数(不绑定自身this,继承外部上下文):arr.forEach(item => console.log(this.num));2. 传入thisArg作为forEach()第二个参数:arr.forEach(function(item) {}, obj)

三、filter():筛选数组的"精准过滤器"

核心功能

filter() 方法用于根据指定条件筛选数组元素,它会返回一个全新的数组(包含所有满足条件的元素),不会修改原始数组。如果没有满足条件的元素,会返回一个空数组。

适用场景

  • 按条件筛选数据(如筛选大于10的数字、筛选成年用户)
  • 排除数组中的无效数据(如筛选非空字符串、排除值为null的元素)
  • 多条件组合筛选(如筛选年龄在20-30岁之间的女性用户)

可运行代码案例

javascript 复制代码
// 1. 基础用法:筛选满足单一条件的元素
const numArr = [12, 5, 28, 7, 35, 1, 40];
// 筛选大于20的数字
const bigNumArr = numArr.filter(num => {
  return num > 20;
});
console.log('原始数组:', numArr); // 输出:[12,5,28,7,35,1,40]
console.log('大于20的数字数组:', bigNumArr); // 输出:[28,35,40]

// 2. 进阶用法:多条件组合筛选
const studentList = [
  { name: '小明', gender: '男', age: 18, score: 90 },
  { name: '小红', gender: '女', age: 17, score: 95 },
  { name: '小刚', gender: '男', age: 19, score: 85 },
  { name: '小丽', gender: '女', age: 18, score: 92 },
  { name: '小亮', gender: '男', age: 17, score: 88 }
];
// 筛选:女性 && 年龄18岁 && 分数大于90
const targetStudents = studentList.filter(student => {
  return student.gender === '女' && student.age === 18 && student.score > 90;
});
console.log('满足条件的学生:', targetStudents); // 输出:[{ name: '小丽', ... }]

// 3. 实战场景:排除无效数据(筛选非空、非undefined的用户名)
const userNameList = ['张三', '', '李四', undefined, '王五', null, '赵六'];
// 筛选有效用户名(排除空字符串、undefined、null)
const validUserNameList = userNameList.filter(name => {
  return name !== '' && name !== undefined && name !== null;
});
console.log('原始用户名列表:', userNameList);
console.log('有效用户名列表:', validUserNameList); // 输出:['张三', '李四', '王五', '赵六']

常见错误与解决方案

常见错误 错误描述 解决方案
错误1:忘记在回调函数中返回判断条件 代码示例:const bigNumArr = numArr.filter(num => { num > 20; }),回调函数无返回值(默认返回undefined),最终返回空数组 1. 显式添加return关键字(如案例1);2. 使用箭头函数简写(省略大括号,自动返回表达式结果):numArr.filter(num => num > 20)
错误2:混淆filter()与forEach(),用filter()执行无返回值的操作 代码示例:numArr.filter(num => console.log(num)),虽能遍历打印,但会额外生成无意义的空数组,造成性能浪费 1. 仅当需要筛选并返回新数组时使用filter();2. 若仅需遍历执行操作(无返回数组需求),使用forEach()/for循环
错误3:筛选引用类型数据时,误判"空对象/空数组"为无效数据 代码示例:const arr = [{}, [], 123]; const newArr = arr.filter(item => item){}[]为真值,会被保留,若需排除空对象/数组则筛选失败 1. 排除空对象:判断对象自身属性数量 Object.keys(item).length > 0;2. 排除空数组:判断数组长度 item.length > 0;3. 组合判断:arr.filter(item => !(Array.isArray(item) && item.length === 0) && !(typeof item === 'object' && item !== null && Object.keys(item).length === 0))
错误4:多条件筛选时逻辑运算符使用错误(&&与||混淆) 代码示例:筛选"年龄18或19岁的女生",误写为student.gender === '女' && student.age === 18 && student.age === 19,无满足条件的元素,返回空数组 1. 明确逻辑关系:"且"用&&,"或"用`

四、sort():排序数组的"灵活排序器"

核心功能

sort() 方法用于对数组元素进行排序,默认情况下按「字符串Unicode编码」升序排列(注意:这是容易踩坑的点),它会直接修改原始数组。同时支持传入自定义比较函数,实现数字升序/降序、对象属性排序等灵活需求。

适用场景

  • 数字数组升序/降序排序(如分数从高到低排序)
  • 字符串数组排序(如按姓名拼音首字母排序)
  • 对象数组按指定属性排序(如按用户年龄、商品价格排序)

可运行代码案例

javascript 复制代码
// 1. 注意点:默认排序(字符串Unicode编码,不适合数字排序)
const defaultNumArr = [10, 2, 35, 7, 100];
defaultNumArr.sort();
console.log('数字默认排序结果:', defaultNumArr); // 输出:[10, 100, 2, 35, 7](不符合预期)

// 2. 基础用法:数字数组升序/降序排序(传入自定义比较函数)
const sortNumArr = [10, 2, 35, 7, 100];
// 数字升序排序:a - b
sortNumArr.sort((a, b) => a - b);
console.log('数字升序排序:', sortNumArr); // 输出:[2, 7, 10, 35, 100]

// 数字降序排序:b - a
sortNumArr.sort((a, b) => b - a);
console.log('数字降序排序:', sortNumArr); // 输出:[100, 35, 10, 7, 2]

// 3. 进阶用法:对象数组按指定属性排序
const goodsList = [
  { name: '手机', price: 4999 },
  { name: '电脑', price: 7999 },
  { name: '平板', price: 2999 },
  { name: '耳机', price: 999 }
];
// 按商品价格升序排序(从便宜到贵)
goodsList.sort((a, b) => a.price - b.price);
console.log('按价格升序排序的商品:', goodsList);
// 输出:[{ name: '耳机', price:999 }, { name: '平板', price:2999 }, ...]

// 按商品价格降序排序(从贵到便宜)
goodsList.sort((a, b) => b.price - a.price);
console.log('按价格降序排序的商品:', goodsList);
// 输出:[{ name: '电脑', price:7999 }, { name: '手机', price:4999 }, ...]

// 4. 实战场景:字符串数组排序(按姓名排序)
const nameList = ['Zhang San', 'Li Si', 'Wang Wu', 'Zhao Liu'];
// 按字符串Unicode编码升序排序(英文姓名适用)
nameList.sort();
console.log('姓名升序排序:', nameList); // 输出:['Li Si', 'Wang Wu', 'Zhang San', 'Zhao Liu']

常见错误与解决方案

常见错误 错误描述 解决方案
错误1:直接对数字数组使用默认sort()排序,结果不符合预期 代码示例:const arr = [10,2,100]; arr.sort();,结果为[10,100,2],而非数字升序[2,10,100] 1. 传入自定义比较函数实现数字排序:升序(a,b) => a - b,降序(a,b) => b - a(如案例2);2. 牢记:默认sort()按字符串Unicode编码排序,不适用数字场景
错误2:对象数组排序时,直接比较对象而非对象的属性 代码示例:goodsList.sort((a,b) => a - b),a和b是对象,无法直接相减,报错NaN,排序失败 1. 排序时指定对象的具体属性:(a,b) => a.price - b.price(如案例3);2. 若属性是字符串,可直接传入属性名(或使用localeCompare()优化中文排序)
错误3:忽略sort()会修改原始数组,导致原数组数据丢失 代码示例:需要保留原始数组,却直接调用arr.sort(),原数组被篡改 1. 排序前先复制原始数组(使用扩展运算符[...arr]Array.from(arr)arr.slice());2. 对复制后的数组执行排序:const sortedArr = [...arr].sort((a,b) => a - b)
错误4:中文字符串排序时,默认sort()结果混乱(按Unicode编码,非拼音/笔画) 代码示例:const chineseArr = ['张三', '李四', '王五']; chineseArr.sort();,排序结果可能不符合中文使用习惯 1. 使用localeCompare()方法优化中文排序:chineseArr.sort((a,b) => a.localeCompare(b, 'zh-CN'));2. 该方法支持按拼音、笔画排序(可配置额外参数)

五、总结

  1. push():尾部追加元素,修改原始数组,返回新长度;避坑重点:不接收返回值作为数组,批量添加用扩展运算符。
  2. forEach() :遍历所有元素,无返回值;避坑重点:无法用return终止遍历,不用于生成新数组。
  3. filter() :条件筛选元素,返回新数组,不修改原数组;避坑重点:必须返回判断条件,区分逻辑运算符&&||
  4. sort():数组排序,修改原始数组,默认按字符串编码排序;避坑重点:数字排序传自定义比较函数,对象排序比较具体属性,需保留原数组先复制。

这四个方法是 JavaScript 数组操作的基础,掌握它们的功能、场景及避坑技巧后,能高效处理大部分数组数据处理需求,所有代码均可直接复制到浏览器控制台或 Node.js 环境中运行验证。

相关推荐
POLITE32 小时前
Leetcode 41.缺失的第一个正数 JavaScript (Day 7)
javascript·算法·leetcode
Filotimo_2 小时前
EntityGraph的概念
java·开发语言·数据库·oracle
wregjru2 小时前
【读书笔记】Effective C++ 条款1~2 核心编程准则
java·开发语言·c++
bjzhang752 小时前
使用 HTML + JavaScript 实现积分抽奖系统
前端·javascript·html
越努力越幸运5082 小时前
vue学习二:
javascript·vue.js·学习
lingran__2 小时前
C语言自定义类型详解 (1.1w字版)
c语言·开发语言
POLITE33 小时前
Leetcode 42.接雨水 JavaScript (Day 3)
javascript·算法·leetcode
京东零售技术3 小时前
2025京东零售技术年度精选 | 技术干货篇(内含福利)
前端·javascript·后端
村口曹大爷3 小时前
JDK 24 正式发布:性能压轴,为下一代 LTS 铺平道路
java·开发语言