js遍历对象篇(一)-for...in和Object.keys

1,212 阅读2分钟

本文总结的方法都无法遍历symbol属性和不可枚举属性,其他方法请看后续文章:

js遍历对象篇(二)-可枚举性和Symbol

js遍历对象篇(三)-Iterator

for...in...遍历对象

// 此代码验证遍历属性的顺序
const obj = {}
obj.name = 'lsc' 
obj.age = 21
obj.aaa = 'aaa'
obj[222] = 222  
obj[111] = 111 
Object.prototype.test = 'test' // 原型链上的属性可以被for...in...遍历
for (let item in obj) {
  console.log(obj[item]);
}
// 111
// 222
// lsc
// 21
// aaa
// test   原型链上的属性
// 返回顺序:首先返回属性名类型是Number的,返回值是按照key从小到大排序,再返回属性名类型是String的,按照属性被创建的时间升序排序

使用for...in...遍历对象的属性名时,要考虑会受到原型属性的影响,可以使用hasOwnProperty加一层过滤以达到Object.keys()的效果,这样的话建议直接使用Object.keys()

Object.keys/values/entries()

console.log(Object.keys(obj)); // [ '111', '222', 'name', 'age', 'aaa' ]
console.log(Object.values(obj)); // [ 111, 222, 'lsc', 21, 'aaa' ]
console.log(Object.entries(obj));
// [
//   [ '111', 111 ],
//   [ '222', 222 ],
//   [ 'name', 'lsc' ],
//   [ 'age', 21 ],
//   [ 'aaa', 'aaa' ]
// ]

Object.keys()和for...in...遍历对象的区别

相同处:

  • 不需要给对象额外部署Symbol.iterator接口(for...of...需要)
  • 返回顺序一样:首先返回属性名类型是Number的,返回值是按照key从小到大排序,再返回属性名类型是String的,按照属性被创建的时间升序排序
  • 不返回属性名为Symbol的属性和不可枚举的属性 不同处:
  • for...in...会返回原型链上的属性,Object.keys()不会

Object.keys()使用场景举例

Vue中过滤器filter的全局定义

import Vue from "vue"
import * as filters from './filter'

Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

Object.entries()使用场景举例

将对象转化为map

let lsc = {
  name: 'lsc',
  age: '21',
  height: 187
};
console.log(Object.entries(lsc)); // [ [ 'name', 'lsc' ], [ 'age', '21' ], [ 'height', 187 ] ]

// let map_test = new Map(lsc)  
// 直接转对象会报错 object is not iterable (cannot read property Symbol(Symbol.iterator))

// 正确方式
let map = new Map(Object.entries(lsc))
console.log(map); // Map(3) { 'name' => 'lsc', 'age' => '21', 'height' => 187 }