JavaScript 进阶(五)---forEach/map/filterevery/some/includes/reduce的详细用法

目录

1. forEach

2. map

3. filter

4. for...in

5. for...of

6. every

7. some

8. includes

9. reduce

举个例子:

使用fliter:

使用 map 来筛选并转换数组

使用 forEach 来筛选并构建数组

总结


1. forEach

- 详解:`forEach` 方法对数组的每个元素执行一次提供的函数。这个方法没有返回值。

-特点:forEach 接收一个箭头函数作为参数,这个箭头函数有两个隐含的参数:xx 和 index。xx是当前正在遍历的数组元素,index 是当前元素的索引

-运用场景:

forEach 没有返回值,它主要用于执行副作用操作,比如打印日志、更新DOM元素等。如果你需要基于数组元素创建一个新数组或者进行条件筛选,那么应该使用 map 或 filter 方法。

- 示例:

 let numbers = [1, 2, 3, 4, 5];
     numbers.forEach((number, index) => {
       console.log(`Index ${index}: ${number}`);
     });
     // 输出:Index 0: 1, Index 1: 2, ..., Index 4: 5

  // 假设我们有一个用户数组
let users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Carol', age: 22 }
];

// 使用 forEach 遍历用户数组
users.forEach(user => {
  // 打印每个用户的姓名和年龄
  console.log(`Name: ${user.name}, Age: ${user.age}`);
});

// 这将输出:
// Name: Alice, Age: 25
// Name: Bob, Age: 30
// Name: Carol, Age: 22

2. map

- 详解:`map` 方法创建一个新数组,其元素是调用 `map` 时提供的函数在每个元素上的返回值。

-特点:

  • 参数:map 方法接受一个函数作为参数,这个函数会在每个数组元素上执行。
  • 返回值:返回一个新数组,包含了原始数组每个元素经过函数处理后的结果。
  • 不改变原始数组:map 不会修改原始数组,它总是返回一个新数组。

-运用场景:

map 是处理数组转换的强大工具,它保持了原始数组不变,同时提供了一种灵活的方式来生成新的数组。

- 示例:

  let numbers = [1, 2, 3, 4, 5];
     let squares = numbers.map(number => number * number);
     console.log(squares); // 输出:[1, 4, 9, 16, 25]

  let users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Carol', age: 22 }
];

let userNames = users.map(user => user.name);

console.log(userNames); // 输出:['Alice', 'Bob', 'Carol']

map 方法的回调函数可以接受三个参数:当前元素、当前元素的索引和整个数组。下面是使用索引作为参数的示例:

let numbers = [10, 20, 30, 40, 50];
let numberedSquares = numbers.map((number, index) => {
  return {
    index: index,
    square: number * number
  };
});

console.log(numberedSquares);
/* 输出:
[
  { index: 0, square: 100 },
  { index: 1, square: 400 },
  { index: 2, square: 900 },
  { index: 3, square: 1600 },
  { index: 4, square: 2500 }
]
*/

3. filter

- 详解:`filter` 方法创建一个新数组,包含通过测试(函数返回 true)的所有元素。

-特点:

  • 参数:filter 方法接受一个函数作为参数,这个函数应该返回 true 或 false。
  • 返回值:返回一个新数组,包含通过测试的元素。
  • 不改变原始数组:filter 不会修改原始数组。

-运用场景:

filter 是一个非常有用的数组方法,特别是当你需要根据某些条件从数组中提取子集时。与 forEach 和 map 相比,filter 专注于条件筛选,而不是执行操作或转换元素。

- 示例:

  let numbers = [1, 2, 3, 4, 5];
     let evenNumbers = numbers.filter(number => number % 2 === 0);
     console.log(evenNumbers); // 输出:[2, 4]

filter 方法的回调函数同样可以接受三个参数:当前元素、当前元素的索引和整个数组。下面是使用索引作为参数的示例

 
let users = [
  { name: 'Alice', age: 24 },
  { name: 'Bob', age: 30 },
  { name: 'Carol', age: 22 },
  { name: 'Dave', age: 29 }
];

let olderUsers = users.filter(user => user.age > 25);

console.log(olderUsers);
/* 输出:
[
  { name: 'Bob', age: 30 },
  { name: 'Dave', age: 29 }
]
*/


4. for...in

- 详解:`for...in` 循环遍历一个对象或数组的可枚举属性。如果数组元素的索引是字符串,这个方法也能正常工作。

- 示例:

  let numbers = [2, 5, 8];
     for (let index in numbers) {
       console.log(`Index ${index} has value ${numbers[index]}`);
     }
     // 输出:Index 0 has value 2, Index 1 has value 5, Index 2 has value 8

5. for...of

- 详解:`for...of` 循环遍历可迭代对象(包括数组)的元素,不需要使用索引。

- 示例:

   let numbers = [2, 5, 8];
     for (let number of numbers) {
       console.log(number);
     }

6. every

- 详解:`every` 方法测试数组的所有元素是否都通过了提供的函数的测试。

- 示例:

  let numbers = [1, 2, 3, 4, 5];
     let allLessThanTen = numbers.every(number => number < 10);
     console.log(allLessThanTen); // 输出:true

7. some

- 详解:`some` 方法测试数组中是否至少有一个元素通过了提供的函数的测试。

- 示例:


     let numbers = [1, 2, 3, 10, 5];
     let anyGreaterThanFive = numbers.some(number => number > 5);
     console.log(anyGreaterThanFive); // 输出:true
 

8. includes

- 详解:`includes` 方法确定一个数组是否包含一个特定的值。

- 示例:

 
     let numbers = [1, 2, 3, 4, 5];
     let containsThree = numbers.includes(3);
     console.log(containsThree); // 输出:true
     

9. reduce

- 详解:`reduce` 方法将数组中的所有元素从左到右(或从右到左)累加到一个单一的值。

-特点:

  • 参数:reduce 方法接受一个函数作为必需参数,该函数具有两个参数:累加器(accumulator)和当前值(currentValue)。
  • 返回值:返回数组元素经过累加器函数处理后的最终结果。
  • 可选参数:reduce 还可以接受一个可选的初始值作为第二个参数,这个值将作为第一次调用回调函数时的第一个参数的值。

- 示例:

  let numbers = [1, 2, 3, 4, 5];
     let sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
     console.log(sum); // 输出:15

l
et numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);

console.log(sum); // 输出:15

l
et names = ['Alice', 'Bob', 'Carol', 'Dave'];
let joinedNames = names.reduce((accumulator, currentValue) => accumulator + ' ' + currentValue);

console.log(joinedNames); // 输出:'Alice Bob Carol Dave'

let users = [
  { name: 'Alice', age: 24 },
  { name: 'Bob', age: 30 },
  { name: 'Carol', age: 22 },
  { name: 'Dave', age: 29 }
];

let totalAge = users.reduce((accumulator, user) => accumulator + user.age, 0);

console.log(totalAge); // 输出:105

这些示例展示了每个方法的基本用法,您可以根据需要调整函数和数组来实现更复杂的操作。

举个例子:

使用 map 或 forEach 来执行类似的筛选功能并不像使用 filter 那样直接,因为 map 和 forEach 不会创建一个新数组来存储符合条件的元素。但是,我们可以用它们来达到类似的效果。下面是如何使用 map 和 forEach 来实现筛选:

使用fliter:

let users = [
  { name: 'Alice', age: 24 },
  { name: 'Bob', age: 30 },
  { name: 'Carol', age: 22 },
  { name: 'Dave', age: 29 }
];

let olderUsers = users.filter(user => user.age > 25);

console.log(olderUsers);
/* 输出:
[
  { name: 'Bob', age: 30 },
  { name: 'Dave', age: 29 }
]
*/

使用 map 来筛选并转换数组

虽然 map 通常用于转换数组,但我们可以通过返回 undefined 来忽略不符合条件的元素,从而实现筛选的效果。但请注意,这种方法不会完全像 filter 那样工作,因为 map 总是会返回一个与原始数组长度相同的数组,如果需要筛选掉的元素会用 undefined 填充。


let users = [
  { name: 'Alice', age: 24 },
  { name: 'Bob', age: 30 },
  { name: 'Carol', age: 22 },
  { name: 'Dave', age: 29 }
];

let olderUsers = users.map(user => user.age > 25 ? user : undefined).filter(Boolean);

console.log(olderUsers);
/* 输出:
[
  { name: 'Bob', age: 30 },
  { name: 'Dave', age: 29 }
]
*/

在这个示例中,我们使用三元运算符 user.age > 25 ? user : undefined 来决定是返回用户对象还是 undefined。然后,我们使用 filter(Boolean) 来移除所有 undefined 值。

使用 forEach 来筛选并构建数组

forEach 本身不返回任何值,但我们可以使用一个回调函数,在这个函数内部将符合条件的元素添加到一个新的数组中。

let users = [
  { name: 'Alice', age: 24 },
  { name: 'Bob', age: 30 },
  { name: 'Carol', age: 22 },
  { name: 'Dave', age: 29 }
];

let olderUsers = [];
users.forEach(user => {
  if (user.age > 25) {
    olderUsers.push(user);
  }
});

console.log(olderUsers);
/* 输出:
[
  { name: 'Bob', age: 30 },
  { name: 'Dave', age: 29 }
]
*/

在这个示例中,我们创建了一个空数组 olderUsers,然后使用 forEach 遍历 users 数组。对于每个用户,我们检查他们的年龄是否大于 25,如果是,我们就使用 push 方法将他们添加到 olderUsers 数组中。

尽管 map 和 forEach 可以被用来实现筛选,但在需要筛选数组时,filter 方法通常是最直接和最清晰的选择。

总结

JavaScript 中的循环和迭代方法各有其特点和适用场景。以下是 `forEach`、`map`、`filter` 和 `reduce` 这几个方法的适用场景总结:

1. **forEach**

- 适用场景:当你需要对数组中的每个元素执行某些操作,但不需要返回任何值或创建新数组时。

- 例子:打印数组中的每个元素,或者对每个元素执行副作用操作(如更新DOM)。

2. **map**

- 适用场景:当你需要基于原始数组的每个元素创建一个新数组,且新数组的每个元素是经过某种操作(如转换或计算)后的值时。

- 例子:创建一个新数组,包含原始数组每个数字的平方,或从对象数组中提取特定属性组成的新数组。

3. **filter**

- 适用场景:当你需要根据特定的条件从数组中筛选出符合条件的元素,并将这些元素组成一个新数组时。

- 例子:从用户数组中筛选出所有年龄大于25岁的用户,或筛选出数组中所有的偶数。

4. **reduce**

- 适用场景:当你需要将数组中的所有元素通过某种操作(如累加、连接或合并)归纳为单个值时。

- 例子:计算数组中所有数值的总和,将数组中的所有字符串元素连接成一个单一的字符串,或将对象数组的某个属性值归纳为一个总和或数组。

5. **for...of**

- 适用场景:当你需要遍历可迭代对象(如数组、字符串、Map、Set等)的元素,并且想要以简洁的方式进行时。

- 例子:打印数组中的每个元素,或在遍历时对每个元素执行某些操作。

6. **for...in**

- 适用场景:当你需要遍历对象的可枚举属性,特别是当你需要获取属性名和属性值时。

- 例子:打印对象中的每个属性及其值。

7. **every**

- 适用场景:当你需要检查数组中的所有元素是否都满足某个条件,并且只需要知道“全部是”或“全部否”的结果时。

- 例子:检查数组中的所有数值是否都大于零。

8. **some**

- 适用场景:当你需要检查数组中是否至少有一个元素满足某个条件,并且只需要知道“至少有一个是”的结果时。

- 例子:检查数组中是否有任何数值大于一百。

9. **includes**

- 适用场景:当你需要检查数组是否包含特定的元素,并且只关心存在性时。

- 例子:检查数组中是否包含某个特定的值。

选择哪种方法取决于你的具体需求,例如是否需要返回新数组、是否需要基于条件进行筛选、是否需要对所有元素执行归纳操作等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值