应组合使用多个API:Object.keys()获自有可枚举属性;Object.getOwnPropertyNames()和getOwnPropertySymbols()覆盖不可枚举及Symbol属性;for...in配合hasOwnProperty区分继承属性;Object.getOwnPropertyDescriptors()获取完整描述符;手动遍历原型链可收集全部属性。

要遍历 JavaScript 原型对象的所有属性并获取成员列表,关键在于区分**自有属性**和**原型链上的继承属性**,同时注意**可枚举性**和**属性描述符**(如 configurable、writable、enumerable)的影响。直接用 for...in 或 Object.keys() 不够全面,需组合使用多个 API。
只获取当前对象的自有可枚举属性
这是最常用场景,适用于快速查看实例自身定义的属性:
-
Object.keys(obj):返回所有自有 + 可枚举属性名数组(不含 Symbol) -
Object.getOwnPropertyNames(obj):返回所有自有属性名(含不可枚举,不含 Symbol) -
Object.getOwnPropertySymbols(obj):返回所有自有 Symbol属性
获取整个原型链上的可枚举属性(包括继承的)
for...in 会遍历对象及其原型链上所有可枚举属性(含继承),但无法区分来源。可配合 hasOwnProperty 过滤:
const props = [];
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
props.push(key); // 自有属性
} else {
props.push(`[inherited] ${key}`); // 来自原型
}
}
完整获取所有自有属性(含不可枚举、Symbol、getter/setter 等)
若需完整信息(比如调试或序列化),应使用 Object.getOwnPropertyDescriptors(obj):
- 返回一个对象,键为属性名,值为完整描述符(含
value、get、set、enumerable、configurable、writable) - 它包含所有自有属性,无论是否可枚举或是否为 Symbol
- 对 Symbol 属性也有效(
Object.getOwnPropertyDescriptors会包含 Symbol 键)
遍历整个原型链并收集所有属性(含不可枚举)
没有内置方法直接做到,但可通过循环 Object.getPrototypeOf() 手动向上遍历:
function getAllPropertyNames(obj) {
const names = new Set();
let current = obj;
while (current && current !== Object.prototype) {
Object.getOwnPropertyNames(current).forEach(n => names.add(n));
Object.getOwnPropertySymbols(current).forEach(s => names.add(s));
current = Object.getPrototypeOf(current);
}
return Array.from(names);
}
注意:这会包含大量内置属性(如 toString、constructor),实际使用时建议过滤掉 Object.prototype 上的通用方法,或按需加白名单。


















