Class methods and this

Topics: General
May 29, 2013 at 11:44 AM
Currently there is an issue with the this keyword. Because of the way JavaScript works, the this keyword does not always refer to the object expected by the TypeScript code.

Example of code that will not work in many situations:

TS
class MyClass {
    myProp: number = 0;
    myMethod() {
        this.myProp = 1;
    }
}
JS
var MyClass = (function () {
    function MyClass() {
        this.myProp = 0;
    }
    MyClass.prototype.myMethod = function () {
        this.myProp = 1;
    };
    return MyClass;
})();
A workaround is this:

TS
class MyClass {
    myProp: number = 0;
    myMethod: () => void;

    constructor() {
        this.myMethod = () => {
            this.myProp = 1;
        }
    }
}
JS
var MyClass = (function () {
    function MyClass() {
        var _this = this;
        this.myProp = 0;
        this.myMethod = function () {
            _this.myProp = 1;
        };
    }
    return MyOtherClass;
})();
The reason the second works is because the _this will always point to the object you except from a TypeScript point-of-view.

This needs to be sorted, either by allowing the first TS syntax to generate the same JS as the second TS syntax, or we need to make another solution. Because it's not really acceptable to have to write every class method as a property if this is supposed to be a properly typed language.
Coordinator
May 29, 2013 at 2:15 PM
Hi lilleaasen,

The 'this' usage in classes has come up a few times on the forums (eg https://typescript.codeplex.com/discussions/437633). The short answer is that we've aligned with ES6 classes for the 1.0 version. This has the side effect that, just like in JavaScript, you have to be aware of the 'usage' of this, and need to take extra care when using a class member in, for example, callbacks.

After 1.0, we may look into extending the classes a la CoffeeScript, to let the user opt in to either the 'this' capturing or ES6 style, but for now we're focusing on making sure we're aligning with the future JavaScript standard so that code can work between the two with ease.
May 29, 2013 at 2:28 PM
Well, what I am suggesting is a compiler-level switch. So my class methods never use any this that I don't expect, but functions outside classes can use whatever this. Wouldn't this be possible?
Coordinator
May 29, 2013 at 4:45 PM
I'm not sure I understand what you're asking. The new JavaScript standard that is currently being developed has specific semantics for how classes work. We wouldn't want to offer a different set of semantics via a commandline switch, because then the same code could mean different things, which would be generally confusing.

How 'this' works is something that gives JavaScript a lot of power, though admittedly it does add its own complexity. With TypeScript, that inherit complexity is already there, and its something users who use TypeScript will need to understand and get comfortable with.