前言
对于前端js使用中,遍历函数是经常用到的,下面就列举一下前端的常见遍历方法
一、没有返回值的方法
for
for遍历应该是最普通也是最常见的遍历,如下:
for (let i = 0; i < 5; i++) {
console.log(i);//0 1 2 3 4 5,i为遍历次数
}
for…in
for…in 语句用于遍历数组或者对象的属性
const person = { id: '1', name: '李子' };
for (let x in person) {
console.log(x, person[x]);
}
//id 1
//name 李子
//x 为对象的属性名:id、name;persion[x]即为对应的属性值了
注意:
1、该用法用于数组遍历时,x则是数组的下标
2、一般用于对象属性遍历居多,不建议对数组使用,原因如下:
const person = [{ id: '1', name: '李子' }];
person.test = '123';
for (let x in person) {
console.log(x, person[x]);
}
//0 { id: '1', name: '李子' }
//test '123'
当数组对象,意外增加了其他的属性时,for…in 并不会忽略该属性,导致出现了我们不想要的结果
forEach
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
const arr = [1, 2, 3];
arr.forEach((item, index) => {
console.log(item, index);
});
// 1 0 [1, 2, 3]
// 2 1 [1, 2, 3]
// 3 2 [1, 2, 3]
//item为当次遍历的值,index为数组下标
注意:
1、forEach() IE9以上才支持
2、调用forEach() 时,必须传入一个回调函数,否则会报错。
3、forEach() 无法中途跳出循环,break命令或return命令都不能奏效。
4、forEach() 无法遍历对象
5、forEach() 对于空数组是不会执行回调函数,且对数组中空元素也不会执行回调函数,比如:
const arr = [1, , 3];
arr.forEach((item, index, arr) => {
console.log(item, index, arr);
});
// 1 0 [1, empty, 3]
// 3 2 [1, empty, 3]
for…of
ES6新引入的for…of遍历,它可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、Generator 对象,以及字符串。
const arr = ['red', 'green', 'blue'];
for (let v of arr) {
console.log(v); // red green blue
}
let map = new Map().set('a', 1).set('b', 2);
for (let [key, value] of map) {
console.log(key + ' : ' + value);
}
// a : 1
// b : 2
//对比for...in的遍历方法,for...of遍历出来的v就是数组的值了
由于for…of 遍历出来的v是数组对应的值,所以当我们需要用到数组的下标的时候可以这么使用,比如:
let arr = ['a', 'b', 'c'];
for (let pair of arr.entries()) {
console.log(pair);
}
// [0, 'a']
// [1, 'b']
// [2, 'c']
注意:
1、for…of无法直接遍历普通的对象。
2、entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值;对于 Set,键名与键值相同。Map 结构的 Iterator 接口,默认就是调用entries方法。
3、不同于forEach方法,它可以与break、continue和return配合使用。
4、由于是ES6新引入的方法,所以一般需要经过label来编译兼容ES5
二、返回值为数组、对象的方法
map
map遍历方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
const arr = [{ name: '李子' }];
const newArr = arr.map((item, index, arr) => {
console.log(item, index, arr);
//{ name: '李子' } 0 [{ name: '李子' }]
return item.name;
});
console.log(newArr);//['李子']
注意:
1、map() 不会对空数组进行检测。
2、map() 不会改变原始数组。
3、map() 每次遍历都会返回一个新的值,所以不适用用来过滤数组中的值
4、map() 关于深浅拷贝,取决于回调函数中return的结果,一般直接return原对象值则属于浅拷贝,所以一般使用场景中,map函数都是浅拷贝的居多,如需深度拷贝,建议直接先拷贝原数组,再做遍历
5、map() 支持IE9及以上版本
find
find() 方法返回通过测试(回调函数内判断)的数组的第一个元素的值。
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const val = arr.find((item, index) => {
console.log(item, index);
return item === 2;
});
//1 0
//2 1
console.log(val);//5
注意:
1、当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。这就是上面代码遍历中只会打印出2行数据的原因。
2、如果没有符合条件的元素返回 undefined
3、find() 对于空数组,函数是不会执行的。
4、find() 并没有改变数组的原始值。
5、find函数只支持IE12及以上的版本,所以一般想要直接使用也是需要label来编译兼容ES5
findIndex
findIndex() 方法返回传入一个测试条件(回调函数)符合条件的数组第一个元素位置下标。
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const index = arr.findIndex((item, index) => {
console.log(item, index);
return item === 2;
});
//1 0
//2 1
console.log(index);//1
注意:
1、当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
2、如果没有符合条件的元素返回 -1
3、findIndex() 对于空数组,函数是不会执行的。
4、findIndex() 并没有改变数组的原始值。
5、findIndex() 只支持IE12及以上的版本,一般想要直接使用也是需要label来编译兼容ES5
filter
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
const arr = [1, 2, 3];
const newArr = arr.find((item, index) => {
console.log(item, index);
return item > 2;
});
//1 0
//2 1
//3 2
console.log(newArr);//[3]
注意:
1、filter() 不会对空数组进行检测。
2、filter() 不会改变原始数组。
3、filter() 如果没有符合条件的元素则返回空数组。
4、filter() 支持IE9及以上版本
由于之前有时候也会混淆了find和filter2个函数,所以顺带把区别列出来一下
返回值:
find返回的是一个元素值,没有则为undefined
filter返回的是一个新数组,没有则为空数组
遍历:
find在找到第一个指定的值时会终止后续的遍历
filter则是会遍历所有的值,返回所有匹配到的值
reduce
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
const arr = [10, 20, 60];
const totalNumber = arr.reduce((total, currentValue, currentIndex) => {
console.log(total, currentValue, currentIndex);
return total + currentValue;
}, 0);
//0 10 0
//10 20 1
//30 60 2
//total是上一次的结果,currentValue是当前遍历出的值,currentIndex当前值的下标
console.log(totalNumber);//90
注意:
1、reduce() 对于空数组是不会执行回调函数的。
2、reduce(function()=>{}, initialValue) 接收2个参数,1为回调函数,2为设定回调函数内total的初始值
3、reduce() 支持IE9及以上版本
4、reduce还有个对应的函数是reduceRight,意思就是从数组的右边往左边遍历
以上都是对于数组的遍历,下面来介绍一下关于ES6对象新增扩展的函数
Object.keys
Object.keys() 方法会返回一个由一个传入对象的自身可枚举属性组成的数组
const obj = { id: 1, name: '李子' };
Object.keys(obj);
//['id','name']
注意:
1、Object.keys() 是由ES5引入的,所以在ES5中,如果传入的参数不是一个对象,浏览器会直接报错,而支持ES6的浏览器并不会报错,如下:
Object.keys("foo");
// TypeError: "foo" is not an object (ES5版本)
Object.keys("foo");
// ["0", "1", "2"] (ES6版本)
2、对于数组的遍历,则是只取出数组的下标,所以一般该函数多用于普通的对象
Object.values
Object.values方法会返回一个由一个传入对象的自身可枚举属性的值组成的数组。
const obj = { id: '1', name: '李子' };
Object.values(obj)
// [‘1’, '李子']
注意:
1、Object.value() 是ES7新引入作为遍历一个对象的补充手段
2、对于数组的遍历,则是取出数组的值,返回的数组跟原来是一致,所以一般不会对数组使用
Object.entries
Object.entries()方法会返回一个由一个传入对象的自身可枚举属性的键值对组成的数组。
const obj = { id: '1', name: '李子' };
Object.entries(obj)
// [ [‘id’, '1'] , ['name', '李子'] ]
注意:
1、Object.entries() 是ES7新引入作为遍历一个对象的补充手段
三、返回值为布尔值的方法
every
every() 方法用于检测数组所有元素是否都符合指定条件(通过回调函数提供)。
const arr = [10, 20, 30];
const checkNumber = arr.every((item, index) => {
console.log(item, index);
return item < 20;
});
//10 0
//20 1
console.log(checkNumber);//false
注意:
1、如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
2、如果所有元素都满足条件,则返回 true。
3、every() 不会对空数组进行检测。
4、every() 不会改变原始数组。
5、every() 支持IE9及以上版本
some
some() 方法用于检测数组中的元素是否满足指定条件(回调函数提供)。
const arr = [10, 20, 30];
const hasNumber = arr.some((item, index) => {
console.log(item, index);
return item === 20;
});
//10 0
//20 1
console.log(hasNumber);//true
注意:
1、如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
2、如果没有满足条件的元素,则返回false。
3、some() 不会对空数组进行检测。
4、some() 不会改变原始数组。
includes
includes() 方法返回一个布尔值,表示某个数组是否包含给定的值。
const arr = [10, 20, 30];
const hasNumber = arr.includes(20, 0);
console.log(hasNumber);//true
注意:
1、includes方法的第二个参数表示搜索的起始位置,默认为0,可以不写。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始
2、includes也是ES6才引入的
总结:
以上就是js常见的新旧遍历基本简单用法。
这篇文章主要还是简单的总结一下,当做API,大家可以收藏一下,忘了的时候可以翻一翻。
对于以上的函数,在不同场景下,还会用到函数之间的组合用法,函数的进阶用法,传送门:js 遍历函数的进阶用法、组合用法;
来源:CSDN
作者:李子玅
链接:https://blog.csdn.net/li459559937/article/details/103801491