JS中的循环(数组篇)

1,132 阅读7分钟

前言

记录一下JS中数组常用的循环方法。

forEach

forEach的使用频率可能在众多方法中位列第一,但是你真的了解它么?

使用语法: arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

参数

  1. callback(当前处理的值,当前处理值下标,当前遍历的数组)
  2. this callback函数中的this指向

返回值

undefined

代码

    let arr=[1,2,3,4,,6,null,undefined,''];
    arr.forEach(console.log)

你会发现它不对未初始化的值进行操作,也就是4,,6中不会被遍历到。

    let arr=[1,2,3,4,5];
    arr.forEach((value,index,arr)=>{
        arr.push(0);
        console.log(value); // 1,2,3,4,5
    })
     console.log(arr);  //[1,2,3,4,5,0,0,0,0,0]

可见遍历的范围是定义好的,也就是第一次执行回调函数时数组的值。调用forEach后添加到数组中的项不会被回调函数访问到。

     let arr = [1, 2, 3, 4, 5];
     arr.forEach((value, index, arr) => {
         arr.unshift(0)
         console.log(value); //1,1,1,1,1
     })
     console.log(arr); //[0, 0, 0, 0, 0, 1, 2, 3, 4, 5]

是不是感觉很矛盾?很打脸?让我慢慢给你分析。

微信图片_20210917002244.png 虽然说范围是固定好了,但是还是可以出去的.

     let arr = [1, 2, 3, 4, 5];
     arr.forEach((value, index, arr) => {
         if(index===2){
            arr.splice(index,1)
         }
         console.log(value);//1,2,3,5
     })
        console.log(arr);//[1,2,4,5]

微信图片_20210917001107.png

最后再说一点,forEach中的循环是不能用return终止的。如果你非要用,那也不是不可以。

     let arr = [1, 2, 3, 4, 5];
     try {
            arr.forEach((value, index) => {
                if (index === 2) {
                    throw new Error('终止')
                }
                console.log(value); //1,2
            })
        } catch ({ message }) {
            console.log(message) //终止
        }

map

map()方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

用法:

使用语法: arr.map(callback(currentValue [, index [, array]])[, thisArg])

参数

  1. callback(当前处理的值,当前处理值下标,当前遍历的数组)
  2. this callback函数中的this指向 返回值

数组

        let arr = [1, 2, 3, 4, 5, , 7, null, undefined];
        let result = arr.map(value=>{
            return value+''
        })
        console.table(result);//['1','2','3','4','5','7','null','undefined']

不对未初始化的值进行任何操作。

        let arr = [1, 2, 3, 4, 5, , 7, null, undefined];
        let result = arr.map(() => { })
        console.table(result);//[undefined*9]

当callback函数没有返回值的时候,返回的数组长度与遍历数组长度一样且值都是undefined。 当在callback函数中改变数组时,操作结果与上述在forEach中一致。偷懒就不再写一遍了

filter

filter()方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素,简单说就是一个过滤的效果

用法

let newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

参数

  1. callback(当前处理的值,当前处理值下标,当前遍历的数组)
  2. this callback函数中的this指向

返回值

数组

        let arr = [0, 1, 2, 3, 4, 5];
        let result = arr.filter(value => {
            return value > 3
        })
        console.table(result); //[4,5]

在回调函数中过滤掉不符合要求的数据。

        let arr = [0, 1, 2, 3, 4, 5];
        let result = arr.filter(value => {
            return 1; //返回一个‘真值’
        })
        console.table(result);//[0, 1, 2, 3, 4, 5]

filter为数组中的每个元素调用一次 callback函数,并利用所有使得 callback 返回 true 或等价于 true 的值的元素创建一个新数组。 同样,在callback函数中改变数组时,操作结果参考上述在forEach。偷懒就不再写一遍了

some

some()方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。

用法

arr.some(callback(element[, index[, array]])[, thisArg] )

参数

  1. callback(当前处理的值,当前处理值下标,当前遍历的数组)
  2. this callback函数中的this指向

返回值

boolean(数组中有至少一个元素通过回调函数的测试就会返回true;所有元素都没有通过回调函数的测试返回值才会为false。)

        let arr=[1,2,3,4,5];

        let result=arr.some(function (value,index,arr) {
            console.log(value);//1,2  [3,4,5]将不会在遍历
            return value===2
        })
        console.table(result);//true

需要注意的是,当callback函数中发现第一个满足测试的值时,不管后续的值是否满足测试就会返回true。

        let arr = [];  //或则[,,,,]
        let result = arr.some(function (value, index, arr) {
            console.log(value);
            return '真值'
        })
        console.table(result);  //false

如果用一个空数组进行测试,在任何情况下它返回的都是false

        let arr=[1,2,3,4,5];

        let result=arr.some(function (value,index,arr) {
            console.log(value);  // 1
            return '真值'
        })
        console.table(result);//true

some()为数组中的每一个元素执行一次 callback函数,直到找到一个使得 callback 返回一个“真值”。如果找到了这样一个值,some() 将会立即返回 true。否则,some()返回 false.

同样,在callback函数中改变数组时,操作结果参考上述在forEach。偷懒就不再写一遍了

every

every()方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

用法

arr.every(callback(element[, index[, array]])[, thisArg])

参数

  1. callback(当前处理的值,当前处理值下标,当前遍历的数组)
  2. this callback函数中的this指向 返回值

boolean(如果回调函数的每一次返回都为'真值',返回 true ,否则返回 false。)

        let arr = [1, 2, 3, 4, 5];

        let result = arr.every(function (value, index, arr) {
            return value>0

        })
        console.log(result);//true
        let arr = [1, 2, 3, 4, 5];

        let result = arr.every(function (value, index, arr) {
            console.log(value); //1
            return value > 2

        })
        console.log(result); //false

这里刚好和some方法的规则相反,在every中只要callback函数找到第一个不符合测试的值时,将直接返回false,后续的值不会再遍历。

        let arr = [];

        let result = arr.every(function (value, index, arr) {
            console.log(value);//不执行
            return false

        })
        console.log(result); //true

这里也和some方法的规则相反,用一个空数组进行测试,在任何情况下它返回的都是true。

find

find()方法返回数组中满足提供的测试函数的第一个元素的值。否则返回undefined。

用法

arr.find(callback[, thisArg])

参数

  1. callback(当前处理的值,当前处理值下标,当前遍历的数组)
  2. this callback函数中的this指向

返回值

数组中第一个满足所提供测试函数的元素的值,否则返回 undefined。

        let arr=[1,2,3,4,5];
        let result=arr.find((value,index,arr)=>{
            console.log(value); //1
            return value>0
        })
        console.log(result); //1
        let arr=[1,2,3,4,5];
        let result=arr.find((value,index,arr)=>{
            console.log(value);//1,2,3,4,5
            return value>6
        })
        console.log(result); //undefined
        let arr = [, 2, , 4];
        let result = arr.find((value, index, arr) => {
            console.log(`index:${index}--value:${value}`);//index:0--value:undefined
            return '真值'
        })
        console.log(result); //undefined

找到数组中第一个满足测试的值,并返回他。找到之后,后续的值将不会再遍历。要是数组中的值都不满足测试将返回undefined

        let arr=[,2,,4]; //稀疏数组
        let result=arr.find((value,index,arr)=>{
            console.log(`index:${index}--value:${value}`);
        })
        console.log(result);

结果:

微信图片_20210927170246.png

注意callback函数会为数组中的每个索引调用即从 到 length - 1,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。

还有一点再说一遍,find方法的返回值要么是数组中的值(从数组中找到第一个满足测试的值),要么就是undefined。

findIndex

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

用法

arr.findIndex(callback[, thisArg])

参数

  1. callback(当前处理的值,当前处理值下标,当前遍历的数组)
  2. this callback函数中的this指向 返回值

数组中通过提供测试函数的第一个元素的索引。否则,返回-1。

        let arr=[1,2,3,4,5];
        let result=arr.findIndex((value,index,arr)=>{
            console.log(value); //1,2
            return value===2
        })
        console.log(result);//1
        let arr=[1,2,3,4,5];
        let result=arr.findIndex((value,index,arr)=>{
            console.log(value);
            return value===6
        })
        console.log(result);

在数组arr中找到第一个值为2的下标。当在数组中找到第一个满足测试的值后,就返回它的下标,后续数组中的值将不会遍历。都找不到就返回-1.

        let arr=[1,2,3,4,5];
        let result=arr.findIndex((value,index,arr)=>{
            console.log(value);//1
            return '真值'
        })
        console.log(result);// 0

需要注意的是,当callback函数的返回值为‘真值’,该方法就会结束,并将当前遍历的值的下标返回。

        let arr = [1, , , 4, 5]; 
        let result = arr.findIndex((value, index, arr) => {
            console.log(value);//1,undefined*2,4,5
            if (value == 5) {
                return '真值'
            }
        })
        console.log(result);// 4

该方法和find一样,callback函数会为数组中的每个索引调用即从 到 length - 1,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。