Search code examples
javascriptkey

JavaScript object property with `get` accessor not in Object.keys()


Let's say I have a class with a public property with only a get accessor. I want to be able to loop through the object keys to process the object.

class Foo {
    get bar() {
        return 'barval';
    }
}

Why is bar not visible when I call Object.keys(...) (or similar functions) or looping through the keys in an object? foo.bar successfully returns barval when requested, but Object.keys(foo) returns an empty array when I expected it to return ["bar"]. Why is this?

Sample output:

const foo = new Foo();
console.log(foo.bar,            // barval
    Object.keys(foo),           // []
    Object.entries(foo),        // []
    Object.values(foo));        // []
for (let key in foo)
    console.log(key, foo[key]); // Never reached

Solution

  • Class getters and setters aren't properties of the class instance so they aren't available in keys, entries or values.

    They are instead members of the object’s prototype. You can iterate through the prototype, and just remove the likes of constructor to leave you with just those which you have declared in your class.

    As far as I'm aware, the only way to do this would be:

    class Foo {
        get bar() {
            return 'barval';
        }
    }
    
    const foo = new Foo();
    
    for (const prop of Object.getOwnPropertyNames(Object.getPrototypeOf(foo))) {
        console.log(prop);
    }

    Returns:

    constructor
    bar