如果我写这样的React类:
class SomeClass extends React.Component {
state = {
someState: this.someRegularFunction(),
someOtherState: this.someArrowFunction()
};
someRegularFunction() {
return "someText";
}
someArrowFunction = () => {
return "someOtherText";
};
}
Webstorm代码协助警告箭头函数this.someArrowFunction()
的调用说:
字段'someArrowFunction'在'state'之后声明,可能尚未分配
如果不警告常规功能this.someRegularFunction()
的调用。
Webstorm是正确的,在调用this.someArrowFunction()
时执行失败:
TypeError:_this.someArrowFunction不是函数
我一直在寻找一些解释这种行为的文档,但一直找不到。
为什么在类中声明之前可以调用常规函数,而不是箭头函数?
因为该代码在功能上与此相同:
class SomeClass extends React.Component {
constructor(...args) {
super(...args);
this.state = {
someState: this.someRegularFunction(),
someOtherState: this.someArrowFunction()
};
this.someArrowFunction = () => {
return "someOtherText";
};
}
someRegularFunction() {
return "someText";
}
}
创建实例时,将按源代码顺序处理字段定义。就好像它们在任何其他代码(在基类中)之前或者在调用super
(在子类中)之后插入构造函数中。
相比之下,someRegularFunction
是原型的一种方法,它是在评估类定义时创建的,而不是在创建实例时创建的。
the proposal for the class fields feature在规范文本中对此进行了介绍。 (阅读规范文本不是为了胆小,但!:-))
旁注:它可以说是风格问题,但是如果你正在使用箭头函数以便它可以使用this
而不必担心它是如何被调用的(例如,作为事件处理程序),你可以考虑将它作为一种方法,然后在构造函数中使用bind
(或者在构造函数中有效地使用):
class SomeClass extends React.Component {
someFunction = this.someFunction.bind(this);
state = {
someState: this.someRegularFunction(),
someOtherState: this.someFunction()
};
someRegularFunction() {
return "someText";
}
someFunction() {
return "someOtherText";
}
}
这可以更好地测试可能需要模拟函数的代码(通过在原型上替换它)。
但同样,它可以说是风格问题。