JavaScript数组的forEach、some、every、map函数用法
存档用,JS数组的方法详见:https://www.runoob.com/jsref/jsref-obj-array.html
1.forEach
let arr = [2,4,6,8,10];
arr.forEach(function (value, index) {
console.log(value, index);
// break; 报错
// continue; 报错
// return false; 不会退出循环
// return true; 不会退出循环
});
依次输出:
2 0
4 1
6 2
8 3
10 4
2.some
遍历
some() 方法会依次执行数组的每个元素:
return true;或return 1;则退出循环;无 return或return false;循环继续执行
返回值
- 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
- 如果没有满足条件的元素,则返回false。
示例
let arr = [2,4,6,8,10];
let result = arr.some(function (value, index) {
console.log(value, index);
if (value > 5) {
return true; // 退出循环
}
});
console.log(result);
依次输出:
2 0
4 1
6 2
true
注意: []数组返回false,即没有符合条件的元素。
3.every
遍历
every() 方法使用指定函数检测数组中的所有元素:
无 return或return false;则退出循环return true;或return 1;则循环继续执行;
返回值
-
如果数组中检测到有一个元素不满足,则整个表达式返回 false,且剩余的元素不会再进行检测。
-
如果所有元素都满足条件,则返回 true。
示例
let arr = [2, 4, 6, 8, 10];
let result = arr.every(function (value, index) {
console.log(value, index);
if (value > 5) {
return 0; // 退出循环
}
return 1;
});
console.log(result);
输出:
2 0
4 1
6 2
false
注意: []数组返回true,即没有不符合条件的元素。
4.map 函数用法详解
map() 方法创建一个新数组,其结果是原数组的每个元素调用指定函数后的返回值。
核心特点:
-
不修改原数组,返回新数组。
-
必须显式 return,否则新数组对应位置为 undefined。
-
无法中途终止循环(类似 forEach,无法使用 break 或 return 提前退出)。
const newArray = arr.map(function(value, index, array) { // 处理逻辑 return newValue; }, thisArg);
参数说明
value:当前处理的元素(必选)。
index:当前元素的索引(可选)。
array:原数组本身(可选)。
thisArg:回调函数中 this 的指向(可选,通常很少使用)。
示例
-
数值转换(简单运算)
const arr = [1, 2, 3, 4]; const doubled = arr.map(num => num * 2); console.log(doubled); // 输出: [2, 4, 6, 8] -
提取对象属性
const users = [ { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 } ]; const names = users.map(user => user.name); console.log(names); // 输出: ['Alice', 'Bob'] -
链式调用(结合 filter)
const numbers = [1, 2, 3, 4]; const squaredEven = numbers .filter(num => num % 2 === 0) // 过滤出偶数 [2, 4] .map(num => num ** 2); // 计算平方 [4, 16] console.log(squaredEven); // 输出: [4, 16] -
处理索引
const arr = ['a', 'b', 'c'];
const indexed = arr.map((value, index) =>${index}:${value});
console.log(indexed); // 输出: ['0:a', '1:b', '2:c']
注意事项
-
原数组不受影响
const arr = [1, 2, 3]; arr.map(num => num * 2); console.log(arr); // 原数组仍为 [1, 2, 3] -
必须显式 return
const arr = [1, 2, 3]; const result = arr.map(() => {}); console.log(result); // 输出: [undefined, undefined, undefined] -
引用类型的浅拷贝问题
const original = [{ x: 1 }, { x: 2 }]; const copy = original.map(item => item); copy[0].x = 100; console.log(original[0].x); // 输出: 100(原数组被修改)
总结
适用场景:数据转换(如格式化、数值计算)、提取属性、生成派生数据。
替代方案:若无需新数组,仅需遍历,使用 forEach;若需过滤,优先使用 filter。
性能:避免在超大数组中使用复杂逻辑,可能影响性能。
5.filter 函数用法详解
核心特点
- 创建新数组:返回一个包含所有通过测试的元素的新数组。
- 不修改原数组:原数组保持不变。
- 必须返回布尔值:回调函数应返回
true(保留元素)或false(丢弃元素)。 - 无法中途退出:与
forEach类似,无法使用break或return提前终止循环。 - 空数组处理:若原数组为空,返回空数组
[]。
语法
const newArray = arr.filter(function(value, index, array) {
// 筛选条件
return condition; // true 或 false
}, thisArg);
参数说明
value:当前处理的元素(必选)。
index:当前元素的索引(可选)。
array:原数组本身(可选)。
thisArg:回调函数中 this 的指向(可选,通常很少使用)。
****示例
1.筛选数值(简单条件)
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // 输出: [2, 4]
2.过滤对象数组
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 17 },
{ name: 'Charlie', age: 30 }
];
const adults = users.filter(user => user.age >= 18);
console.log(adults);
// 输出: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 30 }]
3.结合 map 链式调用
const products = [
{ name: 'Laptop', price: 1000 },
{ name: 'Phone', price: 500 },
{ name: 'Tablet', price: 300 }
];
const affordableProducts = products
.filter(product => product.price < 600) // 筛选价格 <600 的商品
.map(product => product.name); // 提取名称
console.log(affordableProducts); // 输出: ['Phone', 'Tablet']
4.使用索引过滤
const arr = ['a', 'b', 'c', 'd'];
const filtered = arr.filter((value, index) => index % 2 === 0);
console.log(filtered); // 输出: ['a', 'c']
注意事项
- 回调函数需返回布尔值
若返回非布尔值,会隐式转换为布尔值(如 0、""、null 视为 false)。
const arr = [1, 0, '', 'hello', null];
const truthyValues = arr.filter(Boolean);
console.log(truthyValues); // 输出: [1, 'hello']
- 引用类型的浅拷贝问题
若元素是对象,新数组中的对象是原数组的引用(修改会同步):
const original = [{ x: 1 }, { x: 2 }];
const filtered = original.filter(item => item.x > 0);
filtered[0].x = 100;
console.log(original[0].x); // 输出: 100(原数组被修改)
- 处理稀疏数组
空位(如 [1, , 3])会被跳过,回调函数不会执行:
const sparseArr = [1, , 3];
const result = sparseArr.filter(() => true);
console.log(result); // 输出: [1, 3]
总结
适用场景:数据筛选(如条件过滤、去除非真值)、提取符合条件的对象。
链式操作:常与 map、reduce 结合使用,构建数据处理管道。
性能:避免在大数组中使用复杂条件逻辑,可能影响性能。
替代方案:若只需判断是否存在符合条件的元素,使用 some;若需全部满足条件,使用 every。
6.reduce 函数用法详解
核心特点
- 累积计算:将数组元素通过回调函数累积为单个值。
- 灵活返回值:结果可以是任意类型(数值、对象、数组等)。
- 初始值可选:若未提供初始值,默认使用数组第一个元素作为初始值(空数组会报错)。
- 无法中途退出:需遍历所有元素(除非抛出异常)。
语法
const result = arr.reduce(function(accumulator, value, index, array) {
// 累积逻辑
return updatedAccumulator;
}, initialValue);
参数说明
accumulator:累积值(必选,初始为 initialValue 或数组第一个元素)。
value:当前处理的元素(必选)。
index:当前元素的索引(可选)。
array:原数组本身(可选)。
initialValue:初始累积值(可选,但推荐始终提供)。
示例
-
数组求和
const numbers = [1, 2, 3, 4]; const sum = numbers.reduce((acc, num) => acc + num, 0); console.log(sum); // 输出: 10 -
对象属性求和
const orders = [ { product: 'A', price: 10 }, { product: 'B', price: 20 }, { product: 'C', price: 30 } ]; const totalPrice = orders.reduce((acc, order) => acc + order.price, 0); console.log(totalPrice); // 输出: 60 -
数组转对象
const arr = ['id', 'name', 'age']; const obj = arr.reduce((acc, key, index) => { acc[key] = index; // 键名: 元素值,键值: 索引 return acc; }, {}); console.log(obj); // 输出: { id: 0, name: 1, age: 2 } -
计算最大值
const scores = [88, 92, 75, 99, 64]; const max = scores.reduce((acc, score) => Math.max(acc, score), -Infinity); console.log(max); // 输出: 99 -
多维数组扁平化
const nestedArr = [[1, 2], [3, 4], [5, 6]]; const flatArr = nestedArr.reduce((acc, subArr) => acc.concat(subArr), []); console.log(flatArr); // 输出: [1, 2, 3, 4, 5, 6] -
替代链式调用(map + filter)
const numbers = [1, 2, 3, 4]; const doubledEven = numbers.reduce((acc, num) => { if (num % 2 === 0) acc.push(num * 2); return acc; }, []); console.log(doubledEven); // 输出: [4, 8]
注意事项
-
初始值的必要性
空数组必须提供初始值:否则会抛出 TypeError。[].reduce((acc, num) => acc + num); // 报错! [].reduce((acc, num) => acc + num, 0); // 安全返回 0 -
引用类型的累积值
若累积值为对象或数组,修改时需避免副作用(建议返回新对象):
const arr = [{ x: 1 }, { x: 2 }];
const sumX = arr.reduce((acc, item) => {
acc.x += item.x; // 直接修改原对象(不推荐)
return acc;
}, { x: 0 });
console.log(sumX.x); // 输出: 3(但初始值被修改)
- 回调必须返回累积值
未显式 return 会导致后续迭代的 accumulator 为 undefined:
const arr = [1, 2, 3];
const brokenSum = arr.reduce((acc, num) => {
acc + num; // 未返回
}, 0);
console.log(brokenSum); // 输出: undefined
总结
适用场景:复杂聚合(求和、统计、分组)、多维数据处理、替代链式调用。
初始值建议:始终提供初始值以避免空数组报错和逻辑错误。
性能优化:在大数组操作中,注意避免频繁创建新对象或数组。
替代方案:简单的求和或拼接可用 arr.join() 或 arr.flat(),但 reduce 更通用。
浙公网安备 33010602011771号