在类中声明之前调用常规函数与箭头函数

问题描述 投票:1回答:1

如果我写这样的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不是函数


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

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

javascript reactjs function arrow-functions
1个回答
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";
    }
}

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

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

© www.soinside.com 2019 - 2024. All rights reserved.