1、for
普通for循环 是最早出现的遍历语句,能满足开发人员的绝大多数需求。
// 遍历数组
let arr = [1,2,3,4,5];
for(let i = 0; i < arr.length; i++){
console.log(i); // 索引,数组下标 0 1 2 3 4
console.log(arr[i]); // 数组下标所对应的元素 1 2 3 4 5
}
// 遍历对象
let obj = {name:"leo", age:20, country:"China"};
for(let i = 0, keys = Object.keys(obj); i < keys.length; i++){
console.log(keys[i]); // 对象的键值 name age country
console.log(obj[keys[i]]); // 对象的键对应的值 leo 20 China
}
// 遍历字符串
let str = "abcdef";
for(let i = 0; i < str.length; i++){
console.log(i); // 索引,字符串的下标 0 1 2 3 4 5
console.log(str[i]); // 字符串下标所对应的元素 a b c d e f
}
2、forEach
forEach 是ES5版本发布的,按升序为数组中含有效值的每一项执行一次回调函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上),一般认为是 普通for循环 的加强版。
// 遍历数组
let arr = [1,2,3,4,5];
arr.forEach(item => {
console.log(item); // 直接输出了数组的元素 1 2 3 4 5
});
// 遍历对象
let obj = {name:"leo", age:20, country:"China"};
let keys = Object.keys(obj);
keys.forEach(i => {
console.log(i); // 对象的键值 name age country
console.log(obj[i]); // 对象的键对应的值 leo 20 China
});
3、map
map 是ES5版本发布的,遍历时可以返回一个新数组,新数组的结果是原数组中的每个元素都调用一次提供的函数后的返回值。
let arr = [1,2,3,4,5];
let newArr = arr.map(i => i * i);
console.log(newArr); // [1, 4, 9, 16, 25]
4、for in
for in 是ES5版本发布的,以随机顺序遍历一个对象中除 Symbol 以外的可枚举属性(包括原型对象上的可枚举属性)。
// 遍历数组
let arr = [1,2,3,4,5];
for(let i in arr){
console.log(i); // 索引,数组下标 0 1 2 3 4
console.log(arr[i]); // 数组下标所对应的元素 1 2 3 4 5
}
// 遍历对象
let obj = {name:"leo", age:20, country:"China"};
for(let key in obj){
console.log(key); // 对象的键 name age country
console.log(obj[key]); // 对象的键对应的值 leo 20 China
}
// 遍历字符串
let str = "abcdef";
for(let i in str){
console.log(i); // 索引,字符串下标 0 1 2 3 4 5
console.log(str[i]); // 字符串下标所对应的元素 a b c d e f
}
5、for of
for of 是ES6版本发布的,在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。
// 迭代数组
let arr = [1,2,3,4,5];
for(let item of arr){
console.log(item); // 遍历数组元素 1 2 3 4 5
}
// 迭代字符串
let str = "abcdef";
for(let item of str) {
console.log(item); // 遍历字符串元素 a b c d e f
}
// 迭代Map
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
for (let entry of iterable) {
console.log(entry); // 遍历Map中可迭代元素 ["a", 1] ["b", 2] ["c", 3]
}
// 迭代Set
let iterable = new Set([1, 1, 2, 2, 3, 3,4]);
for (let value of iterable) {
console.log(value); // 遍历Set中可迭代元素 1 2 3 4
}
// 迭代arguments类数组对象
function fn(){
for (let argument of arguments) {
console.log(argument);
}
}
fn(1, 2, 3); // 1 2 3
1、场景差异
普通for循环 是最原始的循环语句。定义一个变量 i(数字类型,表示数组的下标),按照一定的条件,对 i 进行循环累加。条件通常为循环数组的长度,当超过长度就停止循环。因为对象无法判断长度,所以通常搭配 Object.keys() 使用。
forEach 一般认为是 普通for循环 的加强版,可以发现它比 普通for循环 在写法上简单了不少,但是本质上也是数组的循环。每个数组元素执行一次回调函数,不改变原数组,返回值是 undefined。
map 给原数组中的每个元素都按顺序调用一次回调函数,返回一个新数组,不改变调用它的原数组本身。
for in 遍历对象上的可枚举属性,包括原型对象上的属性,且按任意顺序进行遍历,即顺序不固定。遍历数组时把数组的下标当作键值,此时的 i 是个字符串型的。它是为遍历对象属性而构建的,不建议与数组一起使用。
for of 用于遍历可迭代对象的数据。
性能比较
在测试环境、测试数据等条件一致的情况下,性能排序基本为:
for > for of > forEach > map > for in