首页 > 解决方案 > 在类中声明之前调用常规函数与箭头函数

问题描述

如果我这样写一个 React 类:

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

    someRegularFunction() {
        return "someText";
    }

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

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

字段 'someArrowFunction' 在 'state' 之后声明,可能尚未分配

If 不警告常规函数的调用this.someRegularFunction()

Webstorm 是正确的,调用时执行失败this.someArrowFunction()

TypeError:_this.someArrowFunction 不是函数


我一直在寻找一些解释这种行为的文档,但一直找不到。

为什么你可以在类中声明它们之前调用常规函数,而不是箭头函数?

标签: javascriptreactjsfunctionarrow-functions

解决方案


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

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是原型的方法,它是在评估类定义时创建的,而不是在创建实例时创建的。

规范文本中的类字段功能提案涵盖了这一点。(不过,阅读规范文本不适合胆小的人!:-))


旁注:这可以说是风格问题,但是如果您正在执行该箭头函数以便它可以使用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";
    }
}

这与可能需要模拟函数的测试代码配合得更好(通过在原型上替换它)。

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


推荐阅读