Search code examples
javascriptbabeljsecmascript-next

Property initializers not defined until declared


I am trying to use property initializers to use arrow functions as methods of a class. But they are not accessible until the method is declared. If i change the order in which they are declared it works.

Is it expected behaviour or is it a babel transpilation

class SampleClass1 {
  method2 = this.method1();
  method1() {
    return "works";
  }
}

console.log((new SampleClass1()).method2); // Works

class SampleClass2 {
  method2 = this.method1();
  method1 = () => {
    return "works";
  }
}

console.log((new SampleClass2()).method2); // Error

Following url is a babel repl instance with the code i want to demonstrate please refer to it.

https://babeljs.io/repl/#?evaluate=true&presets=es2015%2Creact%2Cstage-0%2Cstage-2&experimental=false&loose=false&spec=false&code=class%20SampleClass1%20%7B%0A%20%20method2%20%3D%20this.method1()%3B%0A%20%20method1()%20%7B%0A%20%20%20%20return%20%22works%22%3B%0A%20%20%7D%0A%7D%0A%0Aconsole.log(%22(new%20SampleClass1()).method2%22)%3B%0Aconsole.log((new%20SampleClass1()).method2)%3B%0A%0Aclass%20SampleClass2%20%7B%0A%20%20method2%20%3D%20this.method1()%3B%0A%20%20method1%20%3D%20()%20%3D%3E%20%7B%0A%20%20%20%20return%20%22works%22%3B%0A%20%20%7D%0A%7D%0A%0Aconsole.log(%22(new%20SampleClass2()).method2%22)%3B%0Aconsole.log((new%20SampleClass2()).method2)%3B


Solution

  • Yes, this is expected behaviour. Remember that the syntax from this ESnext proposal draft basically desugars to

    class SampleClass1 {
      constructor() {
        this.method2 = this.method1();
      }
      method1() {
        return "works";
      }
    }
    
    class SampleClass2 {
      constructor() {
        this.method2 = this.method1();
        this.method1 = () => {
          return "works";
        }
      }
    }
    

    And it's obvious that you can call prototype methods from the constructor, but not methods on instance properties that you haven't yet created.