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; 则退出循环;
  • 无 returnreturn 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() 方法使用指定函数检测数组中的所有元素:

  • 无 returnreturn 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 的指向(可选,通常很少使用)。

示例

  1. 数值转换(简单运算)

     const arr = [1, 2, 3, 4];
     const doubled = arr.map(num => num * 2);
     console.log(doubled); // 输出: [2, 4, 6, 8]
    
  2. 提取对象属性

     const users = [
       { name: 'Alice', age: 25 },
       { name: 'Bob', age: 30 }
     ];
     const names = users.map(user => user.name);
     console.log(names); // 输出: ['Alice', 'Bob']
    
  3. 链式调用(结合 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]
    
  4. 处理索引

    const arr = ['a', 'b', 'c'];
    const indexed = arr.map((value, index) => ${index}:${value});
    console.log(indexed); // 输出: ['0:a', '1:b', '2:c']

注意事项

  1. 原数组不受影响

     const arr = [1, 2, 3];
     arr.map(num => num * 2); 
     console.log(arr); // 原数组仍为 [1, 2, 3]
    
  2. 必须显式 return

     const arr = [1, 2, 3];
     const result = arr.map(() => {});
     console.log(result); // 输出: [undefined, undefined, undefined]
    
  3. 引用类型的浅拷贝问题

     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 类似,无法使用 breakreturn 提前终止循环。
  • 空数组处理:若原数组为空,返回空数组 []

语法

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']

注意事项

  1. 回调函数需返回布尔值

若返回非布尔值,会隐式转换为布尔值(如 0、""、null 视为 false)。

const arr = [1, 0, '', 'hello', null];
const truthyValues = arr.filter(Boolean); 
console.log(truthyValues); // 输出: [1, 'hello']
  1. 引用类型的浅拷贝问题

若元素是对象,新数组中的对象是原数组的引用(修改会同步):

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. 处理稀疏数组

空位(如 [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:初始累积值(可选,但推荐始终提供)。

示例

  1. 数组求和

     const numbers = [1, 2, 3, 4];
     const sum = numbers.reduce((acc, num) => acc + num, 0);
     console.log(sum); // 输出: 10
    
  2. 对象属性求和

     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
    
  3. 数组转对象

     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 }
    
  4. 计算最大值

     const scores = [88, 92, 75, 99, 64];
     const max = scores.reduce((acc, score) => Math.max(acc, score), -Infinity);
     console.log(max); // 输出: 99
    
  5. 多维数组扁平化

     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]
    
  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]
    

注意事项

  1. 初始值的必要性
    空数组必须提供初始值:否则会抛出 TypeError。

     [].reduce((acc, num) => acc + num); // 报错!
     [].reduce((acc, num) => acc + num, 0); // 安全返回 0
    
  2. 引用类型的累积值

若累积值为对象或数组,修改时需避免副作用(建议返回新对象):

	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(但初始值被修改)
  1. 回调必须返回累积值

未显式 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 更通用。

posted @ 2025-05-25 15:14  Rain Man  阅读(193)  评论(0)    收藏  举报