object.getownpropertynames只获取对象自身属性名(含不可枚举),不查原型链,因其设计原则是严格限定于直接定义在目标对象上的属性;需手动遍历原型链并合并去重结果。

Object.getOwnPropertyNames 只能获取对象自身的属性名(包括不可枚举的),**不能直接检查原型链上的属性**。它不会遍历原型,这是它的设计原则。
为什么 Object.getOwnPropertyNames 不查原型链?
该方法严格限定于“自身属性”——即直接定义在目标对象上、而非从原型继承来的属性。即使原型上有同名属性,也不会被返回。
例如:
const parent = { a: 1 };
const child = Object.create(parent);
child.b = 2;
console.log(Object.getOwnPropertyNames(child)); // ['b'] —— 只有自身属性
console.log(Object.getOwnPropertyNames(parent)); // ['a']
如何手动检查整个原型链上的所有自有属性名?
需要逐级向上遍历原型链,对每个对象调用 Object.getOwnPropertyNames,再合并结果(注意去重,避免重复收集 Object.prototype 上的通用属性)。
- 用 Object.getPrototypeOf 获取当前对象的原型
- 循环直到原型为 null
- 每次调用 Object.getOwnPropertyNames 并收集结果
- 用 Set 去重,保持顺序可选(按从子到父或反之)
function getAllOwnPropertyNames(obj) {
const names = new Set();
let current = obj;
while (current !== null) {
Object.getOwnPropertyNames(current).forEach(name => names.add(name));
current = Object.getPrototypeOf(current);
}
return Array.from(names);
}
// 示例
const parent = { x: 1 };
const child = Object.create(parent);
child.y = 2;
console.log(getAllOwnPropertyNames(child)); // ['y', 'x']
注意:和 for...in、Object.keys 的区别
对比更常用的遍历方式:
- for...in:遍历自身 + 可枚举的继承属性(含原型链)
- Object.keys:只返回自身且可枚举的属性名
- Object.getOwnPropertyNames:只返回自身所有属性名(含不可枚举)
若你真正想“查看原型链上有哪些属性”,for...in 更贴近语义;但若需包含不可枚举属性,就必须手动遍历原型链并配合 Object.getOwnPropertyNames。
实用建议
- 调试时想快速看某个对象“实际拥有哪些键”,用 Object.getOwnPropertyNames 最准确
- 要检查继承关系中的所有属性(尤其含不可枚举的),必须自己实现原型链遍历
- 避免误以为 Object.getOwnPropertyNames(obj.__proto__) 就是“查原型”——它只是查原型对象自身的属性,不递归其原型











