Search code examples
javascriptjavascript-objectsprivateclass-fields

How to Enumerate Private JavaScript Class Fields


How do we enumerate through private class fields?

class Person {
  #isFoo = true;
  #isBar = false;

  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }

  enumerateSelf() {
    console.log(this);
    // (pub/priv fields shown)

    // enumerate through instance fields
    for (let key in this) {
      console.log(key)
      // (only public fields shown)
    }

    // How do we enumerate/loop through private fields too?
  }
}

new Person('J', 'Doe').enumerateSelf();

Solution

  • It's not possible. They're private fields, and there is no enumeration method for them. Only the class declaration statically knows which ones were declared. They're not properties, there's not even a language value representing a private name, you cannot access them dynamically (like with bracket notation).

    The best you'll get is

    enumerateSelf() {
        console.log(this);
        for (let key in this) {
            console.log("public", key, this[key]);
        }
        console.log("private isFoo", this.#isFoo);
        console.log("private isBar", this.#isBar);
    }
    

    There was an open issue in the private-fields proposal about "Private field iteration", however one of the first comments by a TC39 member states "Private fields are not properties. You can't reflect on them by design.".