JavaScript 遍历方法汇总

对象的遍历与我们形影不离,不管是数组还是一个形如{ key:value} 的对象,很多时候我们都得遍历一个对象。为此有必要把遍历对象的方法整理成章,以备必时之需。

数组遍历

for 循环

for 循环可以说是最原始的遍历方法,常常被用来遍历数组。

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

forEach()

forEach() 方法是用来遍历数组的,它可以接受一个回调函数作为参数。回调函数有两个参数分别是 item (值)和 index (下标)。

let arr = [1,2,3,4,5,6,7];
arr.forEach(function(value,index){
    console.log(value,index);
})

map()

map 方法用于数组的遍历,接受一个函数作为参数,返回一个新的数组。

let arr = [1,2,3,4,5,6,7];
let newArr = arr.map((value, index, array) => value*index);
// 结果:[0, 2, 6, 12, 20, 30, 42]

上面我们使用了箭头函数的简写方式,它会自动把表达式中的结果作为返回值,map() 方法很常用,比如:需要对一个数组进行筛选,对一个对象元素的数组进行属性的过滤。对于对象属性的过滤(重新组装)的简写方式可能有点不同:

const arr = [
  {
    id: 1,
    name: 'a',
    age: 12
  }, {
    id: 2,
    name: 'b',
    age: 24
  }, {
    id: 3,
    name: 'c',
    age: 36
  }
]
let newArr = arr.map(item => ({id: item.id, name: item.name}));
// 结果:[{id: 1, name: "a"}, {id: 2, name: "b"}, {id: 3, name: "c"}]

若想使用箭头函数的的简写,如果是返回一个对象的话,你必需把返回的对象用括号包起来。

filter()

作用就跟它的名字的意思一样,过滤。从数组中过滤出符合条件的元素组成的一个“新数组”,给新数组加个双引号是因为数组中的元素(对象类型)是依然是旧的(旧数组中的元素)

const arr = [
  {
    id: 1,
    name: 'a',
    age: 12
  }, {
    id: 2,
    name: 'b',
    age: 24
  }, {
    id: 3,
    name: 'c',
    age: 36
  }
]
let newArr = arr.filter(item => item.age>18);
// 结果:[{id: 2, name: "b", age: 24}, {id: 3, name: "c", age: 36}]

find()

找到符合条件的元素并返回。如果是空数组,函数不会执行,如果已经找到元素,那么遍历就会停止。

const arr = [
  {
    id: 1,
    name: 'a',
    age: 12
  }, {
    id: 2,
    name: 'b',
    age: 24
  }, {
    id: 3,
    name: 'c',
    age: 36
  }
]
let newArr = arr.find(item => item.age>18);
// 结果:{id: 2, name: "b", age: 24}

findIndex()

与 find() 方法类似,对空数组函数不会执行,如果找到(满足条件)元素,遍历停止,并返回元素所对应的下标,如果没找到,则返回 -1。

const arr = [
  {
    id: 1,
    name: 'a',
    age: 12
  }, {
    id: 2,
    name: 'b',
    age: 24
  }, {
    id: 3,
    name: 'c',
    age: 36
  }
]
let newArr = arr.findIndex(item => item.age>18);
// 结果:1

对象遍历

这里所说的对象遍历包含但不限于数组的遍历方法。

for…in

for…in 方法循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

const obj = {
    name:'云库网',
    domain:'http://yunkus.com',
    age:'2年9月4日',
};
for(key in obj){
    console.log(key,obj[key]);
}

Object.keys()

ES5 方法。Object.keys 方法返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)。

const obj = {
    name:'云库网',
    domain:'http://yunkus.com',
    age:'2年9月4日',
};
for(let key of Object.keys(obj)){
    console.log(key,obj[key]);
}

Object.values()

ES6 方法。Object.values() 方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值。

const obj = {
    name:'云库网',
    domain:'http://yunkus.com',
    age:'2年9月4日',
};
for(let value of Object.values(obj)){
    console.log(value);
}

Object.entries()

ES6 方法。Object.entries() 方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。

const obj = {
    name:'云库网',
    domain:'http://yunkus.com',
    age:'2年9月4日',
};
for(let [key,value] of Object.entries(obj)){
    console.log(key,value);
}

Reflect.ownKeys()

ES6 方法。Reflect.ownKeys() 方法返回一个数组,包含对象自身的所有属性,不管属性名是 Symbol 还是字符串,也不管是否可枚举。

const obj = {
    name:'云库网',
    domain:'http://yunkus.com',
    age:'2年9月4日',
};
for(let key of Reflect.ownKeys(obj)){
    console.log(key,obj[key]);
}

for…of

ES6 方法。for…of 循环可以遍历数组、Set 和 Map 结构、某些类似数组的对象(比如 arguments 对象、DOM NodeList 对象)、Generator 对象,以及字符串。可以 for…of 循环真的是无所不能,但说是这么说,它还是要有个前提的,那就是 一个数组结构只要部署了 Symbol.iterator 属性,也就是说只要有 iterator 接口的,就可以被 for…of 循环遍历。