TypeScript “this” scoping issue when called in jquery callback

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);
    }
}
  • 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
Also as shown:

$(document).ready(thisTest.run.bind(thisTest));
  • Good/bad: Opposite memory/performance trade-off compared to the first method
  • Good: No extra work if the function has parameters
  • Bad: In TypeScript, this currently has no type safety
  • Bad: Only available in ECMAScript 5, if that matters to you
  • Bad: You have to type the instance name twice

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

$(document).ready((n, m) => thisTest.run(n, m));
  • Good/bad: Opposite memory/performance trade-off compared to the first method
  • Good: In TypeScript, this has 100% type safety
  • Good: Works in ECMAScript 3
  • Good: You only have to type the instance name once
  • Bad: You’ll have to type the parameters twice
  • Bad: Doesn’t work with variadic parameters

Leave a Comment