JS遍历方法整理

234 阅读9分钟

JS遍历方法

数组遍历方法

1.forEach()

forEach()方法对数组的每个元素执行一次给定的函数。

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

    为数组中每个元素执行的函数,该函数接收一至三个参数:

    • currentValue 数组中正在处理的当前元素。

    • index 可选 数组中正在处理的当前元素的索引。

    • array 可选 forEach() 方法正在操作的数组。

      let arr = [1, 2, 3, 4, 5]
      arr.forEach((item, index, arr)=>{
          console.log(index + ':' + item);
      })
      
  • thisArg 可选

    可选参数。当执行回调函数 callback 时,用作 this 的值(前提是回调函数不能是箭头函数,因为箭头函数没有this)

    let arr = [1, 2, 3, 4, 5]
    let arr1 = [6, 7, 8, 9, 10];
        arr.forEach(function(item, index, arr){
            console.log(this[index]);
        }, arr1)
    
  • 返回值

    undefind

注意:

  • forEach 方法不会改变原数组,也没有返回值;
  • forEach无法使用 break,continue 跳出循环,使用 return 时,效果和在 for 循环中使用 continue 一致;

2.map()

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

var new_array = arr.map(function callback(currentValue[, index[, array]]) [, thisArg])
  • callback

    生成新数组元素的函数,使用三个参数:

    • currentValue callback 数组中正在处理的当前元素。
    • index可选 callback 数组中正在处理的当前元素的索引。
    • array可选 map 方法调用的数组。
     let arr = [1, 2, 3, 4];
     let new_arr = arr.map((item)=> item);
     console.log(new_arr === arr);  //false
     console.log(new_arr);
    
  • thisArg可选

    执行 callback 函数时值被用作this

  • 返回值

    一个由原数组每个元素执行回调函数的结果组成的新数组。

注意:

  • map 方法遍历数组时会返回一个新数组,不会改变原始数组;

3.for of

for...of语句在可迭代对象(iterator)(包括 ArrayMapSetStringTypedArrayarguments对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

for (variable of iterable) {
    //statements
}
  • variable

    在每次迭代中,将不同属性的值分配给变量。

  • iterable

    被迭代枚举其属性的对象。

let arr = [2, 3, 4, 5, 6];
 for(let item of arr){
        console.log(item);  //2,3,4,5,6
}

注意:

  • 可以使用break、continue来中断循环遍历;
  • for of 方法适用遍历 数组/ 类数组/字符串/map/set 等拥有迭代器对象的集合

4.filter()

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。

  • callback

    用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。它接受以下三个参数:

    • element 数组中当前正在处理的元素。
    • index可选 正在处理的元素在数组中的索引。
    • array可选 调用了 filter 的数组本身。
    let arr = [1, 2, 3, 4, 5, 6];
    let new_arr = arr.filter(item => item%2 === 0);
    console.log(new_arr);   //2,4,6
    
  • thisArg可选

    执行 callback 时,用于 this 的值。

  • 返回值

    一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。

注意:filter()只能用来检测数组。

5.some()、every()

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

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

    用来测试每个元素的函数,接受三个参数: element 数组中正在处理的元素。 index 可选 数组中正在处理的元素的索引值。 array可选 some被调用的数组。

        let arr = [1, 2, 3];
        let even1 = arr.some(item => item%2 === 0);
        console.log(even1); //true
    
  • thisArg可选

    执行 callback 时使用的 this 值。

  • 返回值

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

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

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

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

    用来测试每个元素的函数,它可以接收三个参数: element 用于测试的当前值。 index可选 用于测试的当前值的索引。 array可选 调用 every 的当前数组。

        let arr = [1, 2, 3];
        let even2 = arr.every(item => item%2 === 0);
        console.log(even2); //false
    
  • thisArg

    执行 callback 时使用的 this 值。

  • 返回值

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

注意:若收到一个空数组,此方法在一切情况下都会返回 true

6.reduce()、reduceRight()

reduce() 方法对数组中的每个元素执行一个由您提供的函数(升序执行),将其结果汇总为单个返回值。

reduceRight() 方法和的reduce()用法几乎一致,只是该方法是对数组进行倒序遍历的,而reduce()方法是正序遍历的。

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
  • callback

    执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数,包含四个参数:

    • accumulator 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。
    • currentValue 数组中正在处理的元素。
    • index 可选 数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。
    • array可选 调用reduce()的数组
  • initialValue可选

    作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。

  • 返回值

    函数累计处理的结果

    let arr = [1, 2, 3, 4];
    let info = arr.reduce((sta,item,index,arr)=>{
        console.log(sta,item,index);
        return sta + item;
        // return sta * item;
    }, 5)
    console.log(info);

7.find()、findIndex()

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

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

arr.find(callback[, thisArg])
  • callback

    在数组每一项上执行的函数,接收 3 个参数:

    • element 当前遍历到的元素。
    • index可选 当前遍历到的索引。
    • array可选 数组本身。
  • thisArg可选

    执行回调时用作this 的对象。

  • 返回值

    数组中第一个满足所提供测试函数的元素的值|索引值,否则返回 undefined | -1.

    let array = [5, 12, 8, 13, 24];
        let found1 = array.find(item => item > 10);
        let found2 = [].find(item => item > 10);
        let index1 = array.findIndex(item => item > 10)
        let index2 = [].findIndex(item => item > 10)
        console.log(found1, found2);    //12 undefined
        console.log(index1, index2)     //1 -1
    

8.keys()、values()、entries()

三个方法都返回一个数组的迭代(Iterator)对象,但对象的内容不相同:

  • keys() 返回数组的索引值
  • values() 返回数组的元素
  • entries() 返回数组的键值对
    let arr = ['apply', 'orange', 'banana'];
    let a1 = arr.keys();
    let a2 = arr.values();
    let a3 = arr.entries();
    console.log(a1,a2,a3);  //Array Iterator {}
    let arr1 = Array.from(a1);  // [0, 1, 2]
    let arr2 = Array.from(a2);  //['apply', 'orange', 'banana']
    let arr3 = Array.from(a3);  // [[0,'apply'], [1,'orange'], [2,'banana']]
    console.log(arr1,arr2,arr3);
方法是否改变原数组特点
forEach()没有返回值
map()有返回值,返回一个处理后的新数组
for offor...of遍历具有Iterator迭代器的对象的属性,返回的是数组的元素、对象的属性值,不能遍历普通的obj对象
filter()过滤数组,返回包含符合条件的元素的数组
every()、some()some()只要有一个是true,便返回true;而every()只要有一个是false,便返回false.
find()、findIndex()find()返回的是第一个符合条件的值;findIndex()返回的是第一个返回条件的值的索引值
reduce()、reduceRight()reduce()对数组正序操作;reduceRight()对数组逆序操作
keys()、values()、entries()keys() 返回数组的索引值;values() 返回数组元素;entries() 返回数组的键值对。

对象的遍历方法

1. for in

for...in语句以顺序遍历一个对象的可枚举属性。

for (variable in object)
  statement
  • variable

    在每次迭代时,variable会被赋值为不同的属性名。

  • object

    被迭代的对象。

    let obj = {a:1, b:2, c:3};
        for(let i in obj){
            console.log('键名:', i); //a, b, c
            console.log('键值:',obj[i]);    //1, 2, 3
        }
        let arr = [1, 2, 3];
        for(let i in arr) {
            console.log(arr[i]);     //1,2,3
        }
    

注意:

  • for in 也能用来遍历数组。
  • for in 不仅会遍历当前对象的所以的可枚举属性,还会遍历其原型链上的属性。

2.Object.keys()、Object.values()、Object.entries()

这三个方法都用来遍历对象,它会返回一个由给定对象的自身可枚举属性组成的数组,但返回的内容不同:

  • Object.keys() 返回包含对象键名的数组;
  • Object.values() 返回包含对象键值的数组;
  • Object.entries() 返回包含对象键名和键值的数组
let obj = {
        id: 2,
        name: 'zs',
        age: 21
    }
    console.log(Object.keys(obj));  //[id,name,age]
    console.log(Object.values(obj));    //[2,'zs',21]
    console.log(Object.entries(obj));   //[[id:2],[name:'zs'],[age:21]]
  • Object.keys()方法返回的数组中的值都是字符串。
  • 这些方法遍历的属性值都是自身的可枚举属性。

3. Object.getOwnPropertyNames()

Object.getOwnPropertyNames() 方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。

Object.getOwnPropertyNames(obj)
  • obj

    一个对象,其自身的可枚举和不可枚举属性的名称被返回。

  • 返回值

    在给定对象上找到的自身属性对应的字符串数组。

    let a = ['Hello', 'World'];
     
    Object.keys(a) // ["0", "1"]
    Object.getOwnPropertyNames(a) // ["0", "1", "length"]
    ​
    let obj = {
            id:2,
            name:"zs",
            age:22
        }
        let a = Object.getOwnPropertyNames(obj);
        console.log(a);     //[id,name,age]
    

4.Object.getOwnPropertySymbols()

Object.getOwnPropertySymbols()方法返回一个给定对象自身的所有 Symbol 属性的数组。

Object.getOwnPropertySymbols(obj)
  • obj

    要返回 Symbol 属性的对象。

  • 返回值

    在给定对象自身上找到的所有 Symbol 属性的数组。

    let obj = {
            id: 2,
            [Symbol(name)]:"zs",
            age: 22
        }
        let a1 = Object.getOwnPropertyNames(obj);
        let a2 = Object.getOwnPropertySymbols(obj);
        console.log(a1,a2);
    

5.Reflect.ownKeys()

静态方法 Reflect .ownKeys() 返回一个由目标对象自身的属性键组成的数组,会返回所有属性key。

  • target

    获取自身属性键的目标对象。

  • 返回值

    由目标对象的自身属性键组成的 Array

    var obj = {
        a: 1,
        b: 2
    }
    Object.defineProperty(obj, 'c', {
        value: 3,
        enumerable: false
    })
    ​
    console.log(Object.keys(obj))
    // ["a", "b"]
    console.log(Reflect.ownKeys(obj))
    // ["a", "b", "c"]

    Reflect.ownKeys() :相当于 Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)

    对象方法遍历基本属性遍历原型链遍历不可枚举属性遍历Symbol
    for in
    Object.keys()
    Object.getOwnPropertyNames()
    Object.getOwnPropertySymbols()
    Reflect.ownKeys()

其他遍历方法

1.for

for循环是应该是最常见的循环方式,它由三个表达式组成,分别是声明循环变量、判断循环条件、更新循环变量。这三个表达式用分号分隔。

let arr = [1, 2, 3, 4, 5];
for(let i = 0; i < arr.length; i++){
    console.log(arr[i]);
}

在执行的时候,会先判断执行条件,再执行。for循环可以用来遍历数组,字符串,类数组,DOM节点等。

2.while

while 语句可以在某个条件表达式为真的前提下,循环执行指定的一段代码,直到那个表达式不为真时结束循环。

非真值:false、空字符串、0、null、undefined、NaN。

let num =1;
while (num < 10) {
    console.log(num);
    num++;
}

while 语句可以在某个条件表达式为真的前提下,循环执行指定的一段代码,直到那个表达式不为真时结束循环。

3.do while

do...while 语句创建一个执行指定语句的循环,直到判断值为 false时结束。该方法先执行后判断,所以循环至少会执行一次。

let num = 5;
do {
    console.log(num);
    num--;
}(num > 0);

4.for await of

for await...of方法被称为异步迭代器,该方法是主要用来遍历异步对象。

for await...of 语句会在异步或者同步可迭代对象上创建一个迭代循环,包括 String,Array,类数组,Map, Set和自定义的异步或者同步可迭代对象。这个语句只能在 async function内使用。

function Gen (time) {
  return new Promise((resolve,reject) => {
    setTimeout(function () {
       resolve(time)
    },time)
  })
}
​
async function test () {
   let arr = [Gen(2000),Gen(100),Gen(3000)]
   for await (let item of arr) {
      console.log(Date.now(),item)
   }
}
test()
//1641310310622 2000
// 1641310310623 100
// 1641310311632 3000