object.hasown 和 object.getownpropertynames 解决不同层面问题:前者安全判断单个自有属性(含不可枚举),后者返回所有自有属性名(字符串键);二者可协同使用,但均不处理 symbol 属性,需配合 object.getownpropertysymbols。

Object.hasOwn 和 Object.getOwnPropertyNames 解决的是不同层面的问题,但可以配合使用来更精准地判断和遍历对象的“自有属性”。
Object.hasOwn 用于安全判断单个属性是否为自有属性
它比 obj.hasOwnProperty(key) 更可靠,不会被对象自身覆盖的 hasOwnProperty 方法干扰。适合在不确定对象是否篡改了原型链时做校验。
- 语法简单:Object.hasOwn(obj, key),返回布尔值
- 只检查该 key 是否直接存在于 obj 上(不查原型链)
- 不区分可枚举性,不可枚举属性也能正确识别
- 例如:Object.hasOwn({a: 1}, 'a') → true;Object.hasOwn({}.constructor.prototype, 'toString') → false
Object.getOwnPropertyNames 返回所有自有属性名(含不可枚举)
它提供完整清单,但不告诉你某个具体 key 是否存在——需要你手动查找或过滤。
- 返回数组,包含所有自有属性名(字符串),包括不可枚举的,但不含 Symbol 属性
- 适用于需要遍历、统计、序列化对象自有结构的场景
- 例如:Object.getOwnPropertyNames(Object.assign({}, {x: 1}, Object.defineProperty({}, 'y', {value: 2, enumerable: false}))) → ['x', 'y']
两者协同:先取全量名,再逐个确认或筛选
当你要处理一个对象,并确保只操作其“真正属于它自己”的属性(包括不可枚举的),典型流程是:
- 用 Object.getOwnPropertyNames(obj) 获取全部自有属性名
- 对每个 name,用 Object.hasOwn(obj, name) 再次验证(虽冗余但语义明确,尤其在动态/防御性代码中)
- 或结合 Object.getOwnPropertyDescriptor(obj, name) 进一步判断是否可枚举、是否为访问器等
比如构建一个“深度自有属性快照”函数:
const snapshot = (obj) =>Object.getOwnPropertyNames(obj)
.filter(key => Object.hasOwn(obj, key))
.reduce((acc, key) => {
acc[key] = obj[key];
return acc;
}, {});
注意边界:它们都不处理 Symbol 属性
如果对象有 Symbol 类型的自有属性,这两个方法都看不到。需要搭配 Object.getOwnPropertySymbols() 使用。
- Object.getOwnPropertyNames(obj) → 只返回字符串键
- Object.getOwnPropertySymbols(obj) → 只返回 Symbol 键
- 要获取全部自有键(字符串 + Symbol),需合并两者:[...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)]











