属性初始化器在声明之前未定义

时间:2016-04-03 09:21:58

标签: javascript babeljs ecmascript-next

我正在尝试使用属性初始值设定项将箭头函数用作类的方法。 但是在声明方法之前它们是不可访问的。 如果我改变它们的声明顺序,它就会起作用。

它是预期的行为还是一个巴贝尔翻译

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

以下网址是一个babel repl实例,其中包含我想要演示的代码,请参阅它。

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

2 个答案:

答案 0 :(得分:1)

是的,这是预期的行为。请记住,这个ESnext提案草案的语法基本上是去了

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

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

很明显,您可以从构造函数中调用原型方法,但不能在尚未创建的实例属性上调用方法。

答案 1 :(得分:0)

我将尝试以不同的方式解释它,上下文将是Babel transpilation和ES2016。

分配会创建变量。

SampleClass2 method1中只是一个变量,恰好有一个函数作为其值。

class SampleClass2 {
  method2 = this.method1(); // variable
  method1 = () => {  // oops, variable because of assignment.
    return "works";
  }
}

想想这个,因为构造函数没有构造包含方法的对象,但只有两个变量。

现在,由于您之后定义了method1,因此method2未定义。然后你试着调用一些未定义的东西。

这是错误消息的原因。

如果您删除(),请执行以下操作:

class SampleClass2 {
  method2 = this.method1; // no longer an error
  method1 = () => {
    return "works";
  }
}

在实例化SampleClass2时,您不会收到任何错误。

为什么第一个案例有效?

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

这基本上是说将名为method1的函数放入SampleClass1的原型中,并在构建新对象时,为该方法的返回值指定一个名为method2的变量[sic] ] method1

不要相信原型相关的东西。

在Babel中查看以下代码。

console.log(SampleClass1.prototype.method1) // function body
console.log(SampleClass2.prototype.method1) // nothing

如果我遗漏了某些内容或犯了错误,请告诉我。希望能帮助到你。 :)