在类中声明常规函数之前先调用常规函数vs.箭头函数

时间:2019-03-01 12:43:05

标签: javascript reactjs function arrow-functions

如果我这样编写一个React类:

class SomeClass extends React.Component {
    state = {
        someState: this.someRegularFunction(),
        someOtherState: this.someArrowFunction()
    };

    someRegularFunction() {
        return "someText";
    }

    someArrowFunction = () => {
        return "someOtherText";
    };
}

Webstorm代码帮助警告有关调用箭头函数this.someArrowFunction()的警告:

  

字段“ someArrowFunction”在“状态”之后声明,并且可能   尚未分配

如果没有警告常规函数this.someRegularFunction()的调用。

Webstorm是正确的,使用以下命令调用this.someArrowFunction()时执行失败:

  

TypeError:_this.someArrowFunction不是函数


我一直在寻找解释此行为的文档,但找不到任何文档。

为什么在类中声明常规函数之前,不能调用常规箭头函数?

1 个答案:

答案 0 :(得分:6)

因为该代码在功能上与此相同:

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";
    }
}

与可能需要模拟该功能的测试代码(通过在原型上进行替换)一起使用时效果更佳。

但同样,这可以说是风格问题。