I have an es6-class instance and I need to get all its properties (and inherited properties too). Is there a way to do this without traversing prototype chain?
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"
...(and inherited properties too). Is there a way to do this without traversing prototype chain?
Not if they're non-enumerable, as your b
property is. To enumerate non-enumerable properties (!), you have to use getOwnPropertyNames
(and getOwnPropertySymbols
), and to include inherited ones, you have to loop through the prototype chain.
Which isn't a problem:
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));
Note that I assumed you wanted to skip the ones on Object.prototype
like toString
, hasOwnProperty
, and such. If you want to include those, change the loop condition to o != null
(or just o
if you like that sort of thing).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With