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

时间:2016-10-18 07:31:20

标签: 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"

1 个答案:

答案 0 :(得分: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));




请注意,我认为您希望跳过Object.prototype上的toStringhasOwnProperty等内容。如果您想要包含这些内容,请将循环条件更改为o != null(如果您喜欢此类内容,则将其更改为o。)