JavaScript中如何遍历对象?

JavaScript中如何遍历对象?

今天来点稍微轻松的话题,如何在JavaScript中遍历对象,在平常的工作中,遍历对象是很常见的操作,javascript提供了多种方法来遍历对象的属性。这些方法各有特点,不同的场景需要使用不同的方法。

假设我们有一个Person对象,包含名字和年龄两个属性,下面看看有哪些方式可以遍历这个对象。

js 复制代码
const person = {
  name: 'Philip',
  age: 18,
};

for...in

遍历对象最基本的方式就是使用for...in,这里需要注意区分和for...of的区别。

  • for...in - 遍历可枚举对象,比如Object。
  • for...of - 遍历可迭代对象,比如Array。

在以下代码中,key是每个属性的名字 - 对应name和age,而person[key]则是每个属性的值 - 对应Philip和18。

js 复制代码
for (const key in person) {
  console.log(key, person[key]);
}

输出如下:

复制代码
name Philip
age 18

for...in是遍历对象最基本的方式,需要注意的是它不仅会遍历对象自身的属性,也会遍历原型链上的属性。假设我们在Object.prototype上添加一个属性,那么这个属性也会被遍历到。

js 复制代码
Object.prototype.customProperty = 'Hello World';
for (const key in person) {
  console.log(key, person[key]);
}

输出如下:

复制代码
name Philip
age 18
customProperty Hello World

如果你只想遍历对象自身的属性,可以使用Object.hasOwnProperty方法来过滤掉原型链上的属性。

js 复制代码
for (const key in person) {
  if (person.hasOwnProperty(key)) {
    console.log(key, person[key]);
  }
}

使用for...of + Object.keys

Object.keys方法返回一个对象中所有可枚举属性的键名并放到一个数组里,配合for...of可以很方便地遍历对象的属性。

js 复制代码
for (const key of Object.keys(person)) {
  console.log(key, person[key]);
}

使用for...of + Object.values

如果你只关心对象的值,而不在key的话,那么可以使用Object.values方法,它返回一个包含对象所有可枚举属性值的数组。

js 复制代码
for (const value of Object.values(person)) {
  console.log(value);
}

输出如下:

复制代码
Philip
18

for...of + Object.entries

下面的方法使用for...of进行遍历,我们都知道for..of是用来遍历可迭代对象的,所以Object.entries返回的一定是一个可迭代对象 - 这里是一个二维数组,然后[key, value]是一个解构操作,负责解构内层一维数组中的值并输出。

js 复制代码
for (const [key, value] of Object.entries(person)) {
  console.log(key, value);
}

Object.entries(person)输出如下,可以看作是一个键值对组成的二维数组。

js 复制代码
[[name, 'Philip'], [age, 18]]

使用[key, value]进行解构后正好得到两组数据:

js 复制代码
key = name, value = 'Philip' // 第一组数据
key = age, value = 18 // 第二组数据

Object.entries + forEach

一个更加函数式的写法是使用数组对象上的forEach方法。

js 复制代码
Object.entries(person).forEach(([key, value]) => {
  console.log(key, value);
});

forEach本质上和for...of并无区别,在使用链式操作时,这种方式可读性更好,比如和filter等方法串联调用时。

js 复制代码
Object.entries(person)
  .filter(([key, value]) => key !== 'age') // 过滤掉 age 属性
  .forEach(([key, value]) => console.log(key));

还有一点要注意,那就是forEach是无法中断的,比如不能使用continue或者break来中断循环,但是for...in和for...of则不受此限制。

Reflect.ownKeys

如果你的对象中有Symbol类型的属性,那么可以使用Reflect.ownKeys方法来获取所有属性的键名。

js 复制代码
const person = {
  name: 'Philip',
  age: 18,
  [Symbol('id')]: 123,
};

Reflect.ownKeys(person).forEach(key => {
  console.log(key, person[key]);
});

输出如下:

复制代码
name Philip
age 18
Symbol(id) 123

Reflect.ownKeys是遍历Symbol类型属性的唯一方法。

最后,如果你使用的是TypeScript,那么所有使用了索引操作的遍历方式(比如person[key])都需要添加索引签名,否则TypeScript会报错,具体原因可以看这篇:

好了最后用表格总结一下:

方法 包含继承属性 包含Symbol 包含不可枚举属性 TypeScript支持
for...in ✅ ❌ ❌ 需要索引签名
Object.keys() ❌ ❌ ❌ ✅
Object.values() ❌ ❌ ❌ ✅
Object.entries() ❌ ❌ ❌ ✅
Reflect.ownKeys() ❌ ✅ ✅ ✅

今天就到这里了,今天是我生日,感谢大家的支持,我们明天见!

相关推荐
楠楠子呀29 分钟前
英语、西语、阿语客户各开一个口:多语言获客的分流方案
开发语言·javascript·ecmascript·跨境电商·whatsapp·营销工具
半个落月1 小时前
LangGraph.js 实战:从状态图到分支、循环、检查点与人工中断
javascript·人工智能·langchain
默_笙4 小时前
🧀 让大模型的答案"流"出来:NestJS AI 模块 + SSE + RxJS 实战
javascript·人工智能
mbshqqb4 小时前
TypeScript基础教程之同步生成器
前端·javascript·typescript
尤水就下4 小时前
🔥预热:在线文档的 block 架构是如何实现的(未完待续...)
前端·javascript·架构
全栈项目管理程序猿5 小时前
ArcGIS JS 基础教程(29):CSVLayer 表格点位图层
前端·javascript
骑着蜗牛撵大象3275 小时前
豆包 Seed 驱动的记账智能体:从拍票抽取到月报生成的全链路落地记录
java·前端·javascript·结构化输出·豆包seed·多模态识别·记账系统
溪语流沙5 小时前
【Web全栈进阶】前端世界观:现代工具链与框架为什么存在
前端·javascript·vue.js
kyriewen6 小时前
我逐个测了 JSON.stringify 的 7 个坑:第 1 个就在丢数据
前端·javascript·程序员
song5016 小时前
React Native for OpenHarmony 实战:三方库 react-native-ratings 的鸿蒙化适配指南
javascript·react native·react.js·分类·harmonyos