打字稿中带有胖箭头功能的“ this”范围问题

时间:2019-03-27 14:37:28

标签: javascript typescript ecmascript-6 this arrow-functions

我的小部件类中有以下代码,应该管理一个简单的身份验证弹出窗口。

private showPopupAuth(): void {

    //...just show() and hide() some stuff...

    this.getDiv().find('#cancel').unbind();
    this.getDiv().find('#cancel').click(() => {
        this.clearAuthPopups();                        
    });

    this.getDiv().find('#confirm').unbind();
    this.getDiv().find('#confirm').click(() => {

        let authRequest = new AuthRequest();    
        authRequest.userId = this.userId;
        authRequest.pw = this.getDiv().find('#pw').val();
        this.clearAuthPopups();

        //...do stuff...
    });
}

通过按“取消”按钮可以关闭一个私有功能,该功能可以正常运行。 通过按下确认按钮,我在控制台中收到以下错误

MyWidget.ts:460 Uncaught TypeError: Cannot read property 'userId' of undefined
    at HTMLButtonElement.<anonymous> (MyWidget.ts:460)
    at HTMLButtonElement.dispatch (jquery.js:3)
    at HTMLButtonElement.r.handle (jquery.js:3)

如果我尝试对其进行调试并检查Chrome> Sources> Scope窗口,则会看到以下内容:

内部取消回调

  • 本地:this正确指向MyWidget
  • Closure(showPopupAuth):this正确指向MyWidget

内部确认回调

  • 本地:this未定义
  • Closure(showPopupAuth):this正确指向MyWidget

如果我分别在console.log(this)和两个回调中运行showPopupAuth()

 >   console.log(this)
 <   MyWidget { ..., userId: "the-user-id", ...}

 >   console.log(this)
 <   <button id="cancel">Cancel</button>

 >   console.log(this)
 <   <button id="confirm">Ok</button>

根据控制台,即使我在两个回调中都使用粗箭头,this也会变成HTMLButtonElement。

为什么会这样?发生了什么事?好像示波器浏览器和控制台在说两件事,对我来说都没有意义。


我知道我可以通过简单地声明一个let _this = this并在回调中使用它来解决此问题,但是我想了解问题的根源。

我已经读过TypeScript "this" scoping issue when called in jquery callback,但没有回答我的问题。


更新:按照建议,我检查了生成的js,一切看起来都很好

MyWidget.prototype.showPopupAuth = function () {
    var _this = this;
    this.getDiv().find('#cancel').unbind();
    this.getDiv().find('#cancel').click(function () {
        _this.clearAuthPopups();
    });
    this.getDiv().find('#confirm').unbind();
    this.getDiv().find('#confirm').click(function () {
        var authRequest = new AuthServiceBeans_1.AuthRequest();
        authRequest.userId = _this.userId;
        authRequest.pw = _this.getDiv().find('#pw').val();
        _this.clearAuthPopups();
    });
};

0 个答案:

没有答案