如何迭代对象原型链中的所有属性?

Dig*_*000 5 javascript ecmascript-6

我有一个es6类实例,我需要获取它的所有属性(以及继承的属性).有没有办法在不遍历原型链的情况下做到这一点?

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"
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 7

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

如果他们的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 != Object.prototype; o = Object.getPrototypeOf(o)) {
  for (let name of Object.getOwnPropertyNames(o)) {
    allNames.add(name);
  }
}
console.log(Array.from(allNames));
Run Code Online (Sandbox Code Playgroud)

请注意,我假设你想跳过的那些Object.prototypetoString,hasOwnProperty和这样的.如果你想包含那些,请将循环条件更改为o != null(或者只是o如果你喜欢那种东西).