JavaScript之 数组中 forEach, filter, reduce, every, some, map函数的区别

4 Array.forEach方法

说明

forEach 是数组对象的一个方法,用于对数组的每个元素执行一次提供的函数。

数组对象是:const arr = [ {} , {} ,....]

语法

array.forEach(callback(currentValue [, index [, array]])[, thisArg])

    • currentValue:数组中正在处理的当前元素。
    • index(可选):数组中正在处理的当前元素的索引。
    • array(可选):调用 forEach 方法的数组。
  • thisArg(可选):执行 callback 函数时使用的 this 值。

在编程文档里,使用特定的符号和格式来表明参数是可选的,这种表示方式有助于开发者清晰理解函数或方法的使用方式。以下是常见的参数可选的文档化表示方式:方括号 [] 表示法

这是一种非常普遍的文档化表示方式,像在 Array.prototype.forEach() 方法里,回调函数的参数描述 callback(currentValue [, index [, array]]) 中,方括号 [] 就表明其中的参数是可选的。callback:为数组中每个元素执行的函数,该函数接收三个参数:currentValue, index, array

  1. 只使用currentValue

    const numbers = [1, 2, 3, 4, 5];
    
    // 使用传统函数
    numbers.forEach(function (number) {
        console.log(number);
    });
    
    // 使用箭头函数
    numbers.forEach(number => console.log(number));
    
  2. 使用currentValue和index

    const fruits = ['apple', 'banana', 'cherry'];
    
    fruits.forEach((fruit, index) => {
       console.log(`Index ${index}: ${fruit}`);
    });
    // Index 0: apple
    // Index 1: banana
    // Index 2: cherry
    
  3. 使用currentValue和index和array

    const colors = ['red', 'green', 'blue'];
    
    colors.forEach((color, index, arr) => {
       console.log(`Element ${color} at index ${index} in array ${arr}`);
    });
    // Element red at index 0 in array red,green,blue
    // Element green at index 1 in array red,green,blue
    // Element blue at index 2 in array red,green,blue
    
  4. 使用currentValue和index和array和thisArg

    const obj = {
        multiplier: 2
    };
    
    const nums = [1, 2, 3];
    
    nums.forEach(function (num) {
        console.log(num * this.multiplier);
    }, obj);
    // 2
    // 4
    // 6
    

注意事项

  • 无法中断或跳出循环forEach 方法会遍历数组中的每个元素,不能像 for 循环那样使用 breakcontinue 语句来中断或跳出循环。如果需要提前终止遍历,可以考虑使用 for...of 循环或 everysome 等方法。

    const arr = [1, 2, 3, 4, 5];
    // 以下代码无法提前终止遍历
    arr.forEach(num => {
        if (num === 3) {
            // 这里的 return 只是结束当前回调函数的执行,不会终止整个遍历
            return; 
        }
        console.log(num);
    });
    
  • 空数组不会执行回调函数:如果数组为空,forEach 方法不会执行回调函数。

    const emptyArray = [];
    emptyArray.forEach(item => console.log(item)); 
    // 不会有任何输出,因为数组为空
    

应用场景

  1. 检查元素在数组中的唯一性

    当你需要判断数组中的某个元素是否是唯一的,或者统计某个元素在数组中出现的次数时,可以使用 array 参数来访问整个数组进行比较。

    const numbers = [1, 2, 3, 2, 4];
    
    numbers.forEach((number, index, arr) => {
        const count = arr.filter(num => num === number).length;
        if (count === 1) {
            console.log(`${number} 是数组中唯一的元素,索引为 ${index}`);
        } else {
            console.log(`${number} 在数组中出现了 ${count} 次,当前索引为 ${index}`);
        }
    });
    
  2. 与数组中的其他元素进行计算

    有时候需要将当前元素与数组中的其他元素进行某种计算,例如计算当前元素与数组中所有元素的和。

    const scores = [80, 90, 70, 85];
    
    scores.forEach((score, index, arr) => {
        const totalScore = arr.reduce((sum, current) => sum + current, 0);
        const averageWithoutCurrent = (totalScore - score) / (arr.length - 1);
        console.log(`去掉索引 ${index} 的分数 ${score} 后,平均分是 ${averageWithoutCurrent}`);
    });
    
  3. 动态修改数组

    在某些情况下,你可能需要根据数组中元素的整体情况来动态修改数组中的元素。

    const prices = [10, 20, 30, 40];
    const discountRate = 0.1;
    
    prices.forEach((price, index, arr) => {
        if (arr.every(p => p > 15)) {
            arr[index] = price * (1 - discountRate);
        }
    });
    
    console.log(prices);
    

5 Array.filter(返回满足条件的新数组)

说明

filter() 是 JavaScript 数组对象的一个常用方法,用于创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。下面为你详细介绍其用法:

语法

const newArray = array.filter(callback(element[, index[, array]])[, thisArg])
// callback 用来测试数组每个元素的函数,它接收以下三个参数:
//      element:数组中当前正在处理的元素。
//      index(可选):当前元素在数组中的索引。
//      array(可选):调用 filter() 方法的数组。
//      该函数返回一个布尔值,true 表示该元素会被包含在新数组中,false 则会被排除。
// thisArg(可选):执行 callback 函数时值被用作 this。
// newArray新数组

注意事项

  1. filter() 方法不会改变原数组,而是返回一个新数组。
  2. 如果 callback 函数总是返回 true,则会返回一个与原数组相同的新数组;如果总是返回 false,则会返回一个空数组。
  3. 不能使用breakcontinue 语句来中断或跳出循环

应用场景

  1. 过滤出偶数

    const numbers = [1, 2, 3, 4, 5, 6];
    const evenNumbers = numbers.filter(function(element) {
        return element % 2 === 0;
    });
    console.log(evenNumbers); // 输出: [2, 4, 6]
    
    // 使用箭头函数简化代码
    const evenNumbersArrow = numbers.filter(num => num % 2 === 0);
    console.log(evenNumbersArrow); // 输出: [2, 4, 6]
    

    在这个例子中,filter() 方法遍历 numbers 数组,callback 函数检查每个元素是否为偶数,如果是则返回 true,该元素就会被添加到新数组 evenNumbers 中。

  2. 过滤出长度大于特定值的字符串

    const words = ['apple', 'banana', 'pear', 'kiwi'];
    const longWords = words.filter(word => word.length > 4);
    console.log(longWords); // 输出: ['apple', 'banana']
    

    这里 filter() 方法遍历 words 数组,callback 函数检查每个字符串的长度是否大于 4,符合条件的字符串会被添加到新数组 longWords 中。

  3. 使用 index 参数过滤特定索引的元素

    const letters = ['a', 'b', 'c', 'd', 'e'];
    const filteredLetters = letters.filter((letter, index) => index % 2 === 0);
    console.log(filteredLetters); // 输出: ['a', 'c', 'e']
    
  4. 使用 array 参数进行更复杂的过滤

    const scores = [80, 90, 70, 85];
    const aboveAverage = scores.filter((score, index, arr) => {
        const average = arr.reduce((sum, num) => sum + num, 0) / arr.length;
        return score > average;
    });
    console.log(aboveAverage); 
    

    在这个例子中,callback 函数使用 array 参数(即 arr)计算出数组的平均值,然后过滤出大于平均值的元素。

  5. 使用 thisArg 参数

    const ages = [20, 30, 15, 25];
    const person = { ageLimit: 18 };
    const adults = ages.filter(function(age) {
        return age >= this.ageLimit;
    }, person);
    console.log(adults); // 输出: [20, 30, 25]
    

    这里通过 thisArg 参数(即 person 对象),在 callback 函数中使用 this 来访问 ageLimit 属性进行过滤。

6 Array.reduce(求和)

说明

在 JavaScript 中,reduce 是数组的一个高阶方法,用于对数组中的每个元素执行一个自定义的累加器函数,最终将数组归约为一个单一的值。下面从语法、注意事项和应用场景三个方面详细说明 reduce 的用法。

语法
const sum = arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
// callback:一个回调函数,用于处理数组中的每个元素,它接受四个参数:
//      accumulator:累加器,用于累积回调函数的返回值。它是上一次调用回调函数时返回的结果,或者是初始值 initialValue
//      currentValue:当前正在处理的数组元素。
//      index(可选):当前正在处理的数组元素的索引。
//      array(可选):调用 reduce 方法的数组。
// initialValue(可选):作为第一次调用 callback 函数时的第一个参数的值。如果没有提供 initialValue,则使用数组的第一个元素作为初始值,并且 callback 函数将从数组的第二个元素开始执行。
// 返回值是求和后的数字
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((accumulator, currentValue) => {
    return accumulator + currentValue;
}, 0);
console.log(sum); // 输出: 10

注意事项

  1. 初始值 initialValue 的重要性:

    • 如果不提供 initialValuereduce 会将数组的第一个元素作为初始值,并从第二个元素开始执行回调函数。如果数组为空且没有提供 initialValue,则会抛出 TypeError 错误。

      const emptyArray = [];
      // 会抛出 TypeError 错误
      // const result = emptyArray.reduce((acc, cur) => acc + cur); 
      const resultWithInitial = emptyArray.reduce((acc, cur) => acc + cur, 0);
      console.log(resultWithInitial); // 输出: 0
      
      
  2. 回调函数的返回值
    回调函数的返回值会作为下一次调用回调函数时的 accumulator 参数。因此,确保回调函数返回正确的类型和值非常重要。

  3. 性能考虑
    虽然 reduce 是一个强大的方法,但在处理大型数组时,可能会影响性能。在这种情况下,可以考虑使用更简单的循环来提高性能。

应用场景

  1. 数组求和、求积

    const numbers = [1, 2, 3, 4];
    // 求和
    const sum = numbers.reduce((acc, cur) => acc + cur, 0);
    console.log(sum); // 输出: 10
    // 求积
    const product = numbers.reduce((acc, cur) => acc * cur, 1);
    console.log(product); // 输出: 24
    
  2. 数组扁平化

    const nestedArray = [1, [2, [3, 4], 5], 6];
    const flattenedArray = nestedArray.reduce((acc, cur) => {
        return acc.concat(Array.isArray(cur) ? cur.reduce((subAcc, subCur) => subAcc.concat(subCur), []) : cur);
    }, []);
    console.log(flattenedArray); // 输出: [1, 2, 3, 4, 5, 6]
    
  3. 统计数组中元素的出现次数

    const fruits = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple'];
    const fruitCount = fruits.reduce((acc, cur) => {
        acc[cur] = (acc[cur] || 0) + 1;
        return acc;
    }, {});
    console.log(fruitCount); // 输出: { apple: 3, banana: 2, cherry: 1 }
    
  4. 对象属性值求和

    const students = [
        { name: 'Alice', score: 80 },
        { name: 'Bob', score: 90 },
        { name: 'Charlie', score: 70 }
    ];
    const totalScore = students.reduce((acc, cur) => acc + cur.score, 0);
    console.log(totalScore); // 输出: 240
    

7 Array.every(所有值都满足)

说明

every() 是数组的一个迭代方法,用于测试数组中的所有元素是否都通过了由提供的函数实现的测试。

语法

const result=array.every(callback(element[, index[, array]])[, thisArg])
// callback:用来测试数组每个元素的函数,该函数接收以下三个参数:
//    element:数组中当前正在处理的元素。
//    index(可选):当前元素在数组中的索引。
//    array(可选):调用 every() 方法的数组。
//    callback 函数需要返回 一个布尔值 。如果所有元素的 callback 函数都返回 true,则 every() 方法返回 true;只要有一个元素的 callback 函数返回 false,则 every() 方法返回 false。
// thisArg(可选):执行 callback 函数时值被用作 this。
// result是true||false

注意事项

  1. 空数组的情况:对于空数组,every() 方法总是返回 true。这是因为在空数组中没有元素需要测试,从逻辑上来说,可以认为 “所有元素” 都满足任何条件。

    const emptyArray = [];
    const result = emptyArray.every(item => item > 0);
    console.log(result); // 输出: true
    
  2. 不会改变原数组every() 方法不会修改调用它的原始数组,它只是对数组元素进行测试。

  3. 遍历行为every() 方法会按照数组的索引顺序依次对每个元素调用 callback 函数。一旦 callback 函数返回 falseevery() 方法会立即停止遍历并返回 false,不会继续测试剩余的元素

  4. 稀疏数组every() 方法会跳过稀疏数组中缺少的元素,不会对其调用 callback 函数。

    稀疏数组:const sparseArray = [1, , 3, , 5];

应用场景

  1. 验证数组元素是否都符合某个条件

    可以使用 every() 方法来检查数组中的所有元素是否都满足特定的条件,例如验证数组中的所有数字是否都为正数。

    const numbers = [1, 2, 3, 4, 5];
    const allPositive = numbers.every(num => num > 0);
    console.log(allPositive); // 输出: true
    

8 Array.some(所有值有一个都满足)

说明

在 JavaScript 里,some 是数组的一个原型方法,用于检查数组中是否至少有一个元素满足所提供的测试函数。以下将从语法、注意事项和应用场景三个方面详细介绍其用法。

语法

arr.some(callback(element[, index[, array]])[, thisArg])
// callback:用于测试数组每个元素的函数,它接受三个参数:
//       element:当前正在处理的数组元素。
//       index(可选):当前元素的索引。
//       array(可选):调用 some 方法的数组。
//  thisArg(可选):执行 callback 时使用的 this 值。
// 如果数组中至少有一个元素通过了 callback 函数的测试,则返回 true;否则返回 false。
const numbers = [1, 3, 5, 7, 9];
const hasEvenNumber = numbers.some((number) => {
    return number % 2 === 0;
});
console.log(hasEvenNumber); // 输出: false

注意事项

  1. 空数组调用 some

    当对空数组调用some方法时,无论callback函数是什么,都会返回false。因为空数组中不存在任何元素去满足测试条件。

    const emptyArray = [];
    const result = emptyArray.some((element) => element > 0);
    console.log(result); // 输出: false
    
  2. callback 函数的执行情况

    some方法在找到一个通过测试的元素后就会立即停止遍历数组,不会继续检查剩余的元素。这有助于提高性能,尤其是在处理大型数组时。

    const arr = [1, 2, 3, 4, 5];
    arr.some((element) => {
        console.log(element);
        return element > 2;
    });
    // 输出: 1 2 3
    
  3. thisArg 参数的使用

    如果使用了thisArg参数,callback函数中的this值会指向thisArg。但在箭头函数中,this是由定义时的上下文决定的,thisArg参数对箭头函数无效

    const obj = {
        threshold: 3
    };
    const numbers = [1, 2, 3, 4];
    const result = numbers.some(function (element) {
        return element > this.threshold;
    }, obj);
    console.log(result); // 输出: true
    

应用场景

检查数组中是否存在满足条件的元素
这是 some 方法最常见的应用场景,例如检查数组中是否存在负数。

const numbers = [1, 2, -3, 4, 5];
const hasNegativeNumber = numbers.some((number) => number < 0);
console.log(hasNegativeNumber); // 输出: true

综上所述,some 方法为检查数组元素是否满足特定条件提供了一种简洁高效的方式,在多种场景下都能发挥重要作用。

9 Array.map() 注意和Map区分

1 语法

JavaScript 中的 map() 是数组(Array)对象的一个高阶函数,用于对数组中的每个元素执行指定操作,并返回一个新的数组。它的核心特点是不修改原数组,而是生成一个新数组。

const newArray = arr.map(callback(currentValue[, index[, array]])[, thisArg])
  • 参数
    • callback:处理每个元素的函数,返回值会被添加到新数组中。
      • currentValue:当前处理的元素(必填)
      • index:当前元素的索引(可选)
      • array:原数组(可选)
    • thisArg(可选):执行 callback 时的 this 值(较少使用)。(一般在传统函数中使用)
const numbers = [1,2, , 3, 4];// 稀疏数组
const price  = 14;
const newArr = numbers.map((value,index,numbers)=>{
  numbers[index]=99;// 无法改变原数组
  console.log(value,index);
  return value*2;
})
// 1 0
// 2 1  
// 注意这里少了个2是因为如果数组有空位(稀疏数组),
// map() 会跳过空元素。
// 3 3
// 4 4
console.log(newArr);
// [2, 4, empty, 6, 8]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值