为什么编译器不会将"this"链接转换为上下文无关变量?

Ily*_*nov 7 javascript typescript

假设我有一个班级(非常简单的场景)

class Student
{
    name = "John";

    sayHello()
    {
        console.log("Hi, I'm " + this.name);
    }
}
Run Code Online (Sandbox Code Playgroud)

它由TypeScript编译器编译为:

var Student = (function () {
    function Student() {
        this.name = "John";
    }
    Student.prototype.sayHello = function () {
        console.log("Hi, I'm " + this.name); //here is the problem. Accessing name via this
    };
    return Student;
})();
Run Code Online (Sandbox Code Playgroud)

现在,如果我创建一个对象并调用一个方法,一切正常.

var student = new Student();

student.sayHello(); //prints Hi, I'm John
Run Code Online (Sandbox Code Playgroud)

但是如果我从回调中调用该方法,它就会中断(this正如预期的那样引用一个Window)

setTimeout(student.sayHello); //prints Hi, I'm 
Run Code Online (Sandbox Code Playgroud)

我知道thisJavaScript和C#或Java 之间的区别.我也知道,TypeScript试图解决这个差异.例如这段代码:

class Student
{
    name = "John";

    sayHelloTo(other)
    {
        other(() => this.name);
    }
}
Run Code Online (Sandbox Code Playgroud)

本来应该编译成

var Student = (function () {
    function Student() {
        this.name = "John";
    }
    Student.prototype.sayHelloTo = function (other) {
        //note, the compiler solves the problem by capturing this into local variable
        var _this = this; 
        other(function () {
            return _this.name;
        });
    };
    return Student;
})();
Run Code Online (Sandbox Code Playgroud)

为什么编译器_this在类成员的第一个场景中不会创建类似变量的东西?我希望在下一个代码中看到一些东西(不是真正的输出,这个代码也不正确,只是为了表明我的意图)

var Student = (function () {
    var _this;
    function Student() {
        _this = this; //solves the problem of setTimeout(student.sayHello)
        _this.name = "John";
    }
    Student.prototype.sayHello = function () {
        console.log("Hi, I'm " + _this.name);
    };
    return Student;
})();
Run Code Online (Sandbox Code Playgroud)

我使用过TypeScript v0.9.7编译器

Dic*_*ink 1

您可能想要更改 sayHello 函数,如下所示,使其生成您想要的代码。请注意 sayHello = () => { } 这仍然适用于多个学生,但您的示例并非如此。

class Student
{
    name = "John";

    sayHello = () =>
    {
        console.log("Hi, I'm " + this.name);
    }
}
Run Code Online (Sandbox Code Playgroud)

它将生成如下代码:

function Student() {
    var _this = this;
    this.name = "John";
    this.sayHello = function () {
        console.log("Hi, I'm " + _this.name);
    };
}
Run Code Online (Sandbox Code Playgroud)

另一种可能性是像这样更改对 setTimeout 的调用

setTimeout(() => { student.sayHello() });
Run Code Online (Sandbox Code Playgroud)