打字稿“这个"在 jquery 回调中调用时的范围问题 [英] TypeScript "this" scoping issue when called in jquery callback

查看:25
本文介绍了打字稿“这个"在 jquery 回调中调用时的范围问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定处理this"范围的最佳方法是什么?在打字稿中.

I'm not sure of the best approach for handling scoping of "this" in TypeScript.

以下是我正在转换为 TypeScript 的代码中常见模式的示例:

Here's an example of a common pattern in the code I am converting over to TypeScript:

class DemonstrateScopingProblems {
    private status = "blah";
    public run() {
        alert(this.status);
    }
}

var thisTest = new DemonstrateScopingProblems();
// works as expected, displays "blah":
thisTest.run(); 
// doesn't work; this is scoped to be the document so this.status is undefined:
$(document).ready(thisTest.run); 

现在,我可以将呼叫更改为...

Now, I could change the call to...

$(document).ready(thisTest.run.bind(thisTest));

...确实有效.但这有点可怕.这意味着代码在某些情况下都可以编译并正常工作,但是如果我们忘记绑定作用域,它就会中断.

...which does work. But it's kinda horrible. It means that code can all compile and work fine in some circumstances, but if we forget to bind the scope it will break.

我想要一种在类中完成的方法,这样在使用类时我们就不必担心这个"是什么.范围为.

I would like a way to do it within the class, so that when using the class we don't need to worry about what "this" is scoped to.

有什么建议吗?

另一种有效的方法是使用粗箭头:

Another approach that works is using the fat arrow:

class DemonstrateScopingProblems {
    private status = "blah";

    public run = () => {
        alert(this.status);
    }
}

这是一种有效的方法吗?

Is that a valid approach?

推荐答案

这里有几个选项,每个选项都有自己的权衡.不幸的是,没有明显的最佳解决方案,它实际上取决于应用程序.

You have a few options here, each with its own trade-offs. Unfortunately there is no obvious best solution and it will really depend on the application.

自动类绑定
如您的问题所示:

Automatic Class Binding
As shown in your question:

class DemonstrateScopingProblems {
    private status = "blah";

    public run = () => {
        alert(this.status);
    }
}

  • 好/坏:这会为类的每个实例的每个方法创建一个额外的闭包.如果这个方法通常只用于常规的方法调用,那就有点矫枉过正了.然而,如果它在回调位置被大量使用,那么类实例捕获 this 上下文会更有效,而不是每个调用站点在调用时创建一个新的闭包.
  • 好:外部调用者不可能忘记处理this上下文
  • 优点:TypeScript 中的类型安全
  • 好:如果函数有参数,不需要额外的工作
  • 坏处:派生类无法调用使用 super.
  • 以这种方式编写的基类方法
  • 不好:哪些方法是预先绑定的"以及哪些方法不会在您的类与其使用者之间创建额外的非类型安全契约的确切语义.
    • Good/bad: This creates an additional closure per method per instance of your class. If this method is usually only used in regular method calls, this is overkill. However, if it's used a lot in callback positions, it's more efficient for the class instance to capture the this context instead of each call site creating a new closure upon invoke.
    • Good: Impossible for external callers to forget to handle this context
    • Good: Typesafe in TypeScript
    • Good: No extra work if the function has parameters
    • Bad: Derived classes can't call base class methods written this way using super.
    • Bad: The exact semantics of which methods are "pre-bound" and which aren't create an additional non-typesafe contract between your class and its consumers.
    • Function.bind
      也如图所示:

      $(document).ready(thisTest.run.bind(thisTest));
      

      • 好/坏:与第一种方法相比,内存/性能的权衡相反
      • 好:如果函数有参数,不需要额外的工作
      • 不好:在 TypeScript 中,目前没有类型安全
      • 不好:仅在 ECMAScript 5 中可用,如果这对您很重要
      • 错误:您必须输入两次实例名称
      • 粗箭头
        在 TypeScript 中(出于解释原因,此处显示了一些虚拟参数):

        Fat arrow
        In TypeScript (shown here with some dummy parameters for explanatory reasons):

        $(document).ready((n, m) => thisTest.run(n, m));
        

        • 好/坏:与第一种方法相比,内存/性能的权衡相反
        • 好:在 TypeScript 中,这具有 100% 的类型安全
        • 好:适用于 ECMAScript 3
        • 好:您只需键入一次实例名称
        • 不好:您必须输入两次参数
        • 不好:不适用于可变参数
        • 这篇关于打字稿“这个"在 jquery 回调中调用时的范围问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆