js中遍历对象的几种方法

js中遍历对象的几种方法一 前言我们知道 在 js 的对象中 有下面几种属性 可枚举属性不可枚举属性从原型链上继承的属性以 Symbol 作为 key 值今天 我们就来谈一谈如何遍历这些属性 二 遍历可枚举属性 首先 遍历可枚举属性是非常常见的一个需求 我们平时比较常用的方法是 forin 和 Object keys 这两个方法都能遍历可枚举属性 我们看看如下的代码 letobj name

一、前言

我们知道,在js的对象中,有下面几种属性:

  • 可枚举属性
  • 不可枚举属性
  • 从原型链上继承的属性
  • 以Symbol作为key值

今天,我们就来谈一谈如何遍历这些属性。

二、遍历可枚举属性

  首先,遍历可枚举属性是非常常见的一个需求,我们平时比较常用的方法是for in和Object.keys(),这两个方法都能遍历可枚举属性,我们看看如下的代码:

let obj = { 
    name: "klx", sex: "man", age: 21 } Object.keys(obj).forEach((key, index) => { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); }) //name:klx //sex:man //age:21 for(key in obj) { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); } //name:klx //sex:man //age:21 

  可以看到,他们并没有什么区别。那么,这两个方法是完全一样的吗?我们再来看看下面的代码:

let obj = { 
    name: "klx", sex: "man", age: 21 } let parent = { 
    parentName: "parent", parentSex: "man", parentAge:40 } Object.setPrototypeOf(obj, parent); Object.keys(obj).forEach((key, index) => { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); }) //name:klx //sex:man //age:21 for(key in obj) { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); } //name:klx //sex:man //age:21 //parentName:parent //parentSex:man //parentAge:40 

  这时我们可以看到,第二种方法比第一种多出来几个属性。所以,他们的区别就体现出来了,我们在上面的代码中将obj的原型对象设置为了另一个对象,而for in把原型链上的属性也遍历了出来,但是Object.keys没有。所以,他们两个的区别就是:for in会遍历原型链上的属性,Object.keys不会遍历原型链上的属性。所以,我们平时最好使用Object.keys去遍历对象,会避免一些不必要的麻烦。

二、遍历不可枚举属性

  什么是不可枚举属性?如果不知道这个问题的同学可以参考MDN的介绍,这里我就不详细解释了。我们先来看看下面的代码:

let obj = { 
    name: "klx", sex: "man", age: 21 } Object.defineProperty(obj, 'age', { 
    enumerable:false, configurable:true, writable:true }) Object.keys(obj).forEach((key, index) => { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); }) //name:klx //sex:man for(key in obj) { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); } //name:klx //sex:man 
let obj = { 
    name: "klx", sex: "man", age: 21, } let a = Symbol('a'); obj[a] = 'Symbol'; Object.defineProperty(obj, 'age', { 
    enumerable:false, configurable:true, writable:true }) let parent = { 
    parentName: "parent", parentSex: "man", parentAge:40 } Object.setPrototypeOf(obj, parent); Object.keys(obj).forEach((key, index) => { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); }) //name:klx //sex:man for(key in obj) { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); } //name:klx //sex:man //parentName:parent //parentSex:man //parentAge:40 Object.getOwnPropertyNames(obj).forEach(key => { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); }) //name:klx //sex:man //age:21 

  所以,使用Object.getOwnPropertyNames就能遍历到这个对象除掉以Symbol作为名称的属性,同时也不能遍历到原型链上的属性。

三、遍历以Symbol作为key值的属性

  那么,如果我们想要遍历以Symbol作为key值的属性该怎么办呢?这时我们可以用这个方法:Object.getOwnPropertySymbols。

let obj = { 
    name: "klx", sex: "man", age: 21, } let a = Symbol('a'); obj[a] = 'Symbol'; Object.defineProperty(obj, 'age', { 
    enumerable:false, configurable:true, writable:true }) let parent = { 
    parentName: "parent", parentSex: "man", parentAge:40 } Object.setPrototypeOf(obj, parent); Object.keys(obj).forEach((key, index) => { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); }) //name:klx //sex:man for(key in obj) { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); } //name:klx //sex:man //parentName:parent //parentSex:man //parentAge:40 Object.getOwnPropertyNames(obj).forEach(key => { 
    console.log(`${ 
     key}:${ 
     obj[key]}`); }) //name:klx //sex:man //age:21 Object.getOwnPropertySymbols(obj).forEach(key => { 
    console.log(obj[key]); }) //Symbol 

  那么问题来了,如果我想遍历一个对象上的全部属性,又该怎么做呢?这时我们可以用Reflect.ownKeys()方法来达到我们的目的,他会放回该对象上的所有属性,但是不包括原型链上的属性:

let obj = { 
    name: "klx", sex: "man", age: 21, } let a = Symbol('a'); obj[a] = 'Symbol'; Object.defineProperty(obj, 'age', { 
    enumerable:false, configurable:true, writable:true }) let parent = { 
    parentName: "parent", parentSex: "man", parentAge:40 } Object.setPrototypeOf(obj, parent); console.log(Reflect.ownKeys(obj)); //[ 'name', 'sex', 'age', Symbol(a) ] 

四、遍历自身以及原型链上的所有属性

  那么,如果我不仅仅想遍历自身所有属性,还想遍历原型链上的所有属性,该怎么办?这时,就没有现成的api供我们调用了,但是我们可以自己写一个方法来遍历:

let obj = { 
    name: "klx", sex: "man", age: 21, } let a = Symbol('a'); obj[a] = 'Symbol'; Object.defineProperty(obj, 'age', { 
    enumerable:false, configurable:true, writable:true }) let parent = { 
    parentName: "parent", parentSex: "man", parentAge:40 } Object.setPrototypeOf(obj, parent); function traverse(obj, arr) { 
    arr.push(...Reflect.ownKeys(obj)); if(Object.getPrototypeOf(obj)) { 
    traverse(Object.getPrototypeOf(obj), arr); } return arr; } console.log(traverse(obj, [])); /* [ 'name', 'sex', 'age', Symbol(a), 'parentName', 'parentSex', 'parentAge', 'constructor', '__defineGetter__', '__defineSetter__', 'hasOwnProperty', '__lookupGetter__', '__lookupSetter__', 'isPrototypeOf', 'propertyIsEnumerable', 'toString', 'valueOf', '__proto__', 'toLocaleString' ] */ 

  这样,我们就把该对象以及原型链上的属性全部遍历出来了,当然,你也可以根据自己的需求,利用上述几个方法组合,来遍历自己想要的属性。

五、结语

  不要小看一个简单的问题,其中可能有许多你不知道的小知识。我们平时简单遍历一个对象可能单纯使用for in就能完成我们的工作了,但是这些更多的细节问题你有注意到吗?好了,这篇博客就到这里了,希望能带给大家一些东西~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/178532.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午5:05
下一篇 2026年3月26日 下午5:05


相关推荐

  • 老是记不住事情是怎么回事_laogeshi

    老是记不住事情是怎么回事_laogeshi#ifdef__int64 typedef__int64LL;#else typedeflonglongLL;#endif用%I64d

    2022年8月1日
    7
  • iic通信协议是什么[通俗易懂]

    iic通信协议是什么[通俗易懂] iic通信协议是什么  IIC协议是二线制,信号线包含SDA和SCL,且信号线是双向的,开路结构,需要通过上拉电阻到VCC,具体的电阻值影响的是信号反应速度和驱动能力。  首先,IIC通信与UART,还有SPI统称为串行接口通信,不过它们之间还是有区别的,如UART的负电平逻辑,还有UART通信不需要时钟,只需要特定的波特率即可,SPI与IIC都可以有一个主机,多个从机的情况,…

    2022年6月9日
    51
  • 高通平台8953 Linux DTS(Device Tree Source)设备树详解之三(高通MSM8953 android7.1实例分析篇)[通俗易懂]

    高通平台8953 Linux DTS(Device Tree Source)设备树详解之三(高通MSM8953 android7.1实例分析篇)[通俗易懂]高通平台8953 LinuxDTS(DeviceTreeSource)设备树详解之三(高通MSM8953android7.1实例分析篇)本系列导航:高通平台8953 LinuxDTS(DeviceTreeSource)设备树详解之一(背景基础知识篇)高通平台8953 LinuxDTS(DeviceTreeSource)设备树详解之二(DTS设备树匹配过程)高通平台8953 L…

    2022年10月18日
    6
  • 什么是人工智能,大数据,云计算,物联网系统_5g物联网人工智能大数据

    什么是人工智能,大数据,云计算,物联网系统_5g物联网人工智能大数据人工智能,英文缩写为AI。是利用计算机科学技术研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 大数据,又称巨量资料,指的是所涉及的数据资料量规模巨大到无法通过人脑甚至主流软件工具,在合理时间内达到撷取、管理、处理、并整理成为帮助企业经营决策更积极目的的资讯。 互联网科技发展蓬勃兴起,人工智能时代来临,抓住下一个风口。为帮助那些往想互联网方向转…

    2022年10月6日
    5
  • 进一步详解WSGI

    进一步详解WSGI还是老样子 需要知道什么是 WSGI 一 什么是 WSGI 1 WSGI Web 服务器网关接口 是 python 中所定义的 Web 服务器和 Web 应用程序之间或框架之间的接口标准规范 2 WSGI 接口规范的目的就是规范 Web 服务器与 Web 应用之间的交互 在协议之间进行转换 3 WSGI 将 Web 组件分成三类 Web 服务器 Server Web 中间件与 Web 应用程序

    2026年3月19日
    1
  • 基于springCloud的分布式架构体系

    基于springCloud的分布式架构体系SpringCloud 作为一套微服务治理的框架 几乎考虑到了微服务治理的方方面面 之前也写过一些关于 SpringCloud 文章 主要偏重各组件的使用 本次分享主要解答这两个问题 SpringCloud 在微服务的架构中都做了哪些事情 SpringCloud 提供的这些功能对微服务的架构提供了怎样的便利 我们先来简单回顾一下 我们以往互联网架构的发展情况 传统架构发展史

    2026年3月19日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号