Typescript - “this”在非箭头类方法中未定义 [duplicate]

Typescript - "this" undefined inside a non-arrow class method [duplicate]

提问人:Jonnopon3000 提问时间:6/19/2019 最后编辑:Jonnopon3000 更新时间:11/5/2023 访问量:1274

问:

我知道 JS 和 TS 中的“this”主题已经被许多问题所涵盖,但我无法找到我面临的特定问题的答案。我敢肯定,我只是不了解一些基本的东西,在归结为箭头函数范围规则的堆积如山的问题中,用谷歌搜索是很棘手的。

首先,我正在努力处理的代码在 Node 后端上运行。

因此,我创建了一个控制器类,其方法定义为箭头函数(简化以进行演示):

class UserController extends AbstractController {

    constructor() { ... }

    public async getUsers(x, y): Promise<any> {
        return this.processRequest( ... ); //processRequest is a protected async definition on AbstractController
    } 
}

// ...
export default new UserController()

我遇到的问题是里面是,我自然希望它是执行它的实例。thisgetUsers()undefinedUserController

如果我确实转换为箭头函数...getUsers

class... {
    public getUsers = async (x, y): Promise<any> => {
        return this.processRequest( ... );
    }
}

...然后它按预期工作。

我相信我了解箭头函数捕获在周围范围方面的工作原理;但在这种情况下,我觉得我错过了两个关键的理解:this

  • 为什么第一种方法没有?我觉得应该是 的实例,如果不是,那么至少它应该是一些更全局的对象。thisthisUserController
  • 为什么第二种方法有效?没有“周围范围”可以捕获 - 是吗?this

调用方式如下:getUsers()

import UserController from 'user.controller';

userRouter.get('/', authMiddleWare, UserController.getUsers);
javascript typescript 这个

评论

3赞 T.J. Crowder 6/19/2019
问题是你在哪里打电话,你没有向我们展示。getUsers
0赞 T.J. Crowder 6/19/2019
“为什么第二种方法有效?没有“周围范围”可以捕捉到这一点——是吗?是的,有:你在那里所做的是公共属性上的初始值设定项。 对于属性,初始值设定项是构造函数中的内容。(实际上,属性初始值设定项在调用 if any 之后重新定位到构造函数。详情请见此处thisthissuper
2赞 T.J. Crowder 6/19/2019
当你查看你的通话方式时,你几乎肯定会发现这个问题的答案(很可能)和/或这个问题答案(更普遍)涵盖了这个问题。:-)getUser
1赞 Ruan Mendes 6/19/2019
UserController.getUsers 应该是 .请参阅TJ的链接问题。否则,您将传递对非 arow 函数的松散引用,这就是未定义的原因。它将是您未处于严格模式的全局对象。如果你仔细阅读问题,你应该能够理解UserController.getUsers.bind(UserController)
2赞 T.J. Crowder 6/19/2019
正如我上面提到的,这是这个问题的重复。强烈建议使用标准的 TypeScript/JavaScript 命名约定,例如 而不是使用的名称来表示 insatnce。这只会误导任何试图阅读代码的人。import controller from 'user.controller'

答:

0赞 Ehsan Moallaee 11/5/2023 #1

这取决于你如何调用你的方法, 在常规函数中,其内部的 this 值是动态的,这取决于函数的调用方式。 与常规函数不同,箭头函数没有自己的此绑定。如果我们在箭头函数中访问 this,它将返回最接近的非箭头父函数的 this。 箭头函数中的 this 值是在声明时确定的,并且永远不会更改。所以 call、apply、bind 不能改变箭头函数的值。 这篇文章完整地解释了它: 如何在回调中访问正确的“this”