Search code examples
javascriptecmascript-next

How to iterate over properties of an ES6/2015 class instance


given these two classes

class Foo{
  f1;

  get f2(){
    return "a";
  }
}

class Bar extends Foo {
  b1;

  get b2(){
    return "a";
  }
}

let bar = new Bar();

What code will get me this list of properties from the bar instance? ['f1', 'f2', 'b1', 'b2']

Here is a Babel sample


Update

This should be part of @Marc C's answer:

Using a decorator I can easily turn a non enumerable property into an enumerable property:

class Bar extends Foo {

  @enumerable()  
  get b2(){
    return "a";
  }

}

Here is the decorator source:

function enumerable() {
  return function(target, key, descriptor) {
    if (descriptor) {
      descriptor.enumerable = true;
    }
  };
}

Here is a Babel sample


Solution

  • That's not valid syntax for declaring properties in a class. Instead, declare them in the constructor.

    class Foo {
      constructor() {
        this.f1 = undefined;
      }
    }
    

    Then you can get them using Object.keys.

    Using experimental features in Babel will allow you to declare properties using that syntax but their values must be declared.

    class Foo {
      f1 = 0;
      ...
    }
    

    As for accessing the getters, getters are non-enumerable by default and can't be accessed using Object.keys or any similar mechanism. However, you can create enumerable getters using Object.defineProperty.

    Object.defineProperty(bar, 'f2', {
      get() { 
        return "a"; 
      }
    });
    

    If you're using experimental ES7 features, you can apply a decorator to the class method and get the same behavior. See this Babel sample.

    class Foo {
      @enumerable()
      get b2() {
        return "a";
      }
    }
    
    function enumerable() {
      return function(target, key, descriptor) {
        if (descriptor) {
          descriptor.enumerable = true;
        }
      }
    }