Object.keys()返回对象自身可枚举属性名数组,Object.getOwnPropertyNames()返回所有自身属性名(含不可枚举)。核心区别在于是否包含不可枚举属性:前者仅enumerable为true的自有属性,后者包含全部自有属性,均不遍历原型链。

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() 是补充角色:
立即学习“Java免费学习笔记(深入)”;
- 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']










