登录
首页 >  文章 >  前端

Object.keys与getOwnPropertyNames区别解析

时间:2026-04-04 10:36:14 495浏览 收藏

想精准控制对象属性的遍历与操作?关键在于理解Object.keys()与Object.getOwnPropertyNames()的本质差异:前者只返回对象自身可枚举(enumerable: true)的属性名,是日常数据处理、表单提取和JSON序列化的得力助手;后者则无差别列出所有自有属性(含不可枚举的如constructor、自定义隐藏字段等),专为调试、元编程和深度克隆等需要完整属性掌控的场景而生——两者均不触及原型链,但决定了你“看到”的到底是对象表面的可用字段,还是它全部的真实面貌。

JavaScript中Object-keys与getOwnPropertyNames对比

Object.keys() 返回对象自身可枚举(enumerable)的属性名数组;Object.getOwnPropertyNames() 返回对象自身所有属性名(包括不可枚举属性)的数组。核心区别在于是否包含不可枚举属性。

只关心“能遍历到的属性”用 Object.keys()

它忽略不可枚举属性,也跳过原型链上的属性,只返回当前对象上 enumerable: true 的自有属性键。

  • for...in 循环默认行为类似,但会遍历原型链;Object.keys() 不会
  • JSON.stringify() 序列化时也只处理可枚举属性,和 Object.keys() 范围一致
  • 常见用途:快速获取可被遍历、映射、过滤的字段,比如表单数据提取、浅拷贝可枚举属性

需要“完整自有属性清单”用 Object.getOwnPropertyNames()

它不区分 enumerable,只要属性是对象自身的(非继承),就全部列出。

  • 能拿到 constructor、toString 等原生不可枚举方法(在普通对象上通常看不到,但在某些内置对象或 defineProperty 设置后会出现)
  • 配合 Object.getOwnPropertyDescriptor() 可进一步判断每个属性是否可枚举、可配置、可写
  • 适合调试、元编程、深克隆实现中需完整属性控制的场景

两者都不管原型链,但还有个更底层的 API

如果连原型链上的属性都想检查,得用 Object.getPrototypeOf() 配合递归调用;而 Object.getOwnPropertySymbols()Reflect.ownKeys() 是补充角色:

  • Object.getOwnPropertySymbols():只取自身 Symbol 类型的属性名
  • Reflect.ownKeys(obj):等价于 [ ...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj) ],最完整的自有键列表

一个小例子看差异

const obj = { a: 1 };
Object.defineProperty(obj, 'b', {
  value: 2,
  enumerable: false // 不可枚举
});
Object.defineProperty(obj, 'c', {
  value: 3,
  enumerable: true
});

console.log(Object.keys(obj));           // ['a', 'c']
console.log(Object.getOwnPropertyNames(obj)); // ['a', 'b', 'c']

理论要掌握,实操不能落!以上关于《Object.keys与getOwnPropertyNames区别解析》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>