如何遍历对象的原型链中的所有属性

How to iterate over all properties in object's prototype chain?

本文关键字:原型 属性 对象 何遍历 遍历      更新时间:2023-09-26

我有一个es6-class实例,我需要得到它的所有属性(和继承的属性)。有没有办法在不遍历原型链的情况下做到这一点?

class A {
  get a() {
    return 123;
  }
}
class B extends A {
  get b() {
    return 456; 
  }
}
const b = new B();
for (let prop in b) {
  console.log(prop); //nothing
}
console.log(Object.keys(b)); //empty array
console.log(Object.getOwnPropertyNames(b)); //empty array
console.log(Reflect.ownKeys(b)); //empty array
console.log(Object.keys(Object.getPrototypeOf(b))); //empty array
console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(b))); //["contructor", "b"] -- without "a"
console.log(Reflect.ownKeys(Object.getPrototypeOf(b))); //["contructor", "b"] -- without "a"

…(以及继承的属性)。有没有办法在不遍历原型链的情况下做到这一点?

如果它们是不可枚举的,就像你的b属性一样。要枚举不可枚举的属性(!),您必须使用getOwnPropertyNames(和getOwnPropertySymbols),并且要包含继承的属性,您必须遍历原型链。

这不是问题:

class A {
    get a() {
        return 123;
    }
}
class B extends A {
    get b() {
        return 456; 
    }
}
const b = new B();
let allNames = new Set();
for (let o = b; o && o != Object.prototype; o = Object.getPrototypeOf(o)) {
    for (let name of Object.getOwnPropertyNames(o)) {
        allNames.add(name);
    }
}
console.log(Array.from(allNames));

注意,我假设您想跳过toStringhasOwnPropertyObject.prototype上的内容。如果您想要包含这些,请将循环条件更改为o != null(或者如果您喜欢这种东西,则更改为o)。