【问题标题】:Can I access the other this in a TypeScript lambda?我可以在 TypeScript lambda 中访问另一个 this 吗?
【发布时间】:2023-03-16 15:33:02
【问题描述】:

在打字稿中,我可以这样写:

$('#something').fadeOut(400, (): void => {
    this.invokeAnotherMethod();
});

编译后,TypeScript 会自动确保 this 指向我的类而不是封闭的函数:

var _this = this;
$('#something').fadeOut(400, function() {
    _this.invokeAnotherMethod();
});

但是,当我需要访问真实的 this 而不是外部的 _this 时呢?是否有语法来引用它?例如,我如何编写可以编译为以下内容的代码:

var _this = this;
$('#something').fadeOut(400, function() {
    $(this).data('specialhide', true);
    _this.invokeAnotherMethod();
});

有可能吗?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您需要避免使用粗箭头语法来执行此操作,因为您不想保留 this 的词法范围。

    var _me = this;
    $('#something').fadeOut(400, function () {
        _me.invokeAnotherMethod();
        $(this).data('specialhide', true);
    });
    

    在此示例中,我使用 _me 而不是 _this 来避免与 TypeScript 生成的变量发生任何冲突。我也避开了self,以避免与window.self 混淆(感谢RockResolve)。

    为什么!

    ECMAScript 6 规范具有箭头函数定义 - 这是 TypeScript 语言从这里获取此特性的地方。当 TypeScript 未来以 ECMAScript 6 为目标时,它将保留 () => 语法 - 因此他们无法使其在 this 的两个上下文中都工作,而不会破坏未来的兼容性。

    尽管您可以想象他们如何更改 TypeScript 编译器以使 _thisthis 在 ECMAScript 3 或 5 中都可用,但它实际上会在版本 6 中成为问题。

    【讨论】:

    • 谢谢,这正是我目前正在做的,隐藏self 并在没有箭头功能的情况下使用它。只是想知道是否还有其他方法。
    • 谨防使用“自我”一词。内置的窗口变量“self”可能会引起混淆(它在调试时让我感到困惑),最好选择另一个词。
    【解决方案2】:

    我想出了一条出路,正如我在回答中所述: How can I preserve lexical scope in TypeScript with a callback function

    这是实现史蒂夫芬顿在回答中所做的关闭的更好方法。我更喜欢它,因为方法签名记录了用法。

    基本上,使用这样的方法:

    fadeOutLambda(outerThis: YourClass): {(d: number, i: number): number}{
        return function(d: number, i: number){
            // Put your "fadeOut" logic here
            // refer to "this" to mean the dynamically scoped "this"
            // refer to "outerThis" to refer to the class instance
            alert(outerThis); // lexically scoped class instance
            alert(this); // dynamically scoped context caller
            return 999;
        }
    }
    

    【讨论】:

    • 您还可以通过简单地获取 this 的局部变量来避免传入“outerThis”,从而简化对fadeOutLambda 的调用。例如fadeOutLambda() { var that = this;返回函数() { ... }; }
    • 我做了一个“照我说的做,而不是照我做的做”,因为 Tyson 提供的方式是我为大多数 lambda 函数做的方式。使用 outerThis 作为参数是为了明确提醒调用者该方法不能按原样调用来执行计算,并且必须调用其结果函数。也就是说,我们称之为 this.fadeOutLambda(this)()。 IDE 会提醒程序员这一点,而如果我们使用“var that = this”作为闭包,则没有提醒。防御性编程反对使用fadeOutLambda() 而不是this.fadeOutLambda()(),如果他们想直接调用它。
    【解决方案3】:

    让我提供另一种不使用 lambda 的解决方案。 您可以将主 this 作为属性附加(在本例中称为 me)。

    class MyClass
    {
        constructor()
        {
            var button: HTMLElement = document.getElementById("buttonID");
            (button as any).me = this;
            button.onclick = this.buttonClick;
        }
    
        private buttonClick(e): boolean
        {
            var me: MyClass = (this as any).me;
    
            // Implementation using this (the button) and me (the class)
    
            return false;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-04
      • 1970-01-01
      • 2021-10-19
      • 2011-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多