I'm not sure of the best approach for handling scoping of "this" in 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.
Any suggestions?
Update
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:
this
context instead of each call site creating a new closure upon invoke.this
contextsuper.
Function.bind
Also as shown:
Fat arrow
In TypeScript (shown here with some dummy parameters for explanatory reasons):
In your code, have you tried just changing the last line as follows?
Another solution that requires some initial setup but pays off with its invincibly light, literally one-word syntax is using Method Decorators to JIT-bind methods through getters.
I've created a repo on GitHub to showcase an implementation of this idea (it's a bit lengthy to fit into an answer with its 40 lines of code, including comments), that you would use as simply as:
I haven't seen this mentioned anywhere yet, but it works flawlessly. Also, there is no notable downside to this approach: the implementation of this decorator -- including some type-checking for runtime type-safety -- is trivial and straightforward, and comes with essentially zero overhead after the initial method call.
The essential part is defining the following getter on the class prototype, which is executed immediately before the first call:
Full source
The idea can be also taken one step further, by doing this in a class decorator instead, iterating over methods and defining the above property descriptor for each of them in one pass.
Necromancing.
There's an obvious simple solution that doesn't require arrow-functions (arrow-functions are 30% slower), or JIT-methods through getters.
That solution is to bind the this-context in the constructor.
You can use this method to automatically bind all function in the class in the constructor: