为什么 TypeScript 需要 "internal" 模块的 "this." 前缀?

Why does TypeScript need the "this." prefix for "internal" modules?

TypeScript 中定义模块的方式有两种:

"Singleton" 生活方式:

import app = require("durandal/app");
import ko = require("knockout");

export var name = ko.observable();

export function sayHello() {
    app.showMessage('Hello ' + name() + '! Nice to meet you.', 'Greetings');
}

"Transient" 生活方式:

import app = require("durandal/app");
import ko = require("knockout");

class AnythingYouLike {
    name = ko.observable();

    sayHello() {
        app.showMessage('Hello ' + this.name() + '! Nice to meet you.', 'Greetings');
    }
}

export = AnythingYouLike;

我在这些不同的方式中使用引号来定义模块,因为我无法弄清楚 "official" 名称是什么。

使用 "transient" 样式,尤其是在使用像 Durandal 这样的框架时,这是很有意义的,因为您可以更好地控制视图模型模块的生活方式并避免尴尬的错误。一个缺点是你必须在任何地方使用 "this",这有两个问题:

  1. 将模块从一种样式更改为另一种样式很乏味。
  2. this. 洒得到处都是噪音。

为什么实际上有必要使用 this.,为什么两种样式都不需要?

这与其说是关于模块,不如说是关于第二个 "style," nameAnythingYouLike [ 的成员这一事实=50=],而在第一个 "style" 中,您将其声明为全局 space 中的自变量。

this 在前一种情况下是有意义的,当您意识到 class 的特定实例正在使用它来引用它自己的 name - this.name ,阅读:"my name"。

当然,在第一个示例中没有这样的上下文 - 您只是在创建 name

@War10ck 正确地指出这是一个非常基本的 OOP 东西。

回复您的评论:

But in the second example, there is context (the surrounding class declaration) that should mean this. can be implied, no?

Java 以这种方式工作(其他 OOP 语言也是如此),this 的语义在 TS 和 Java 中或多或少是相同的。但是不行,this 不能隐含在 TS 中,它必须是显式的。

请注意,这主要是 因为 "singleton style" 存在于 JS 中,因此在 TS 中存在扩展,而 [=46] 中不存在=].为了说明,请考虑如果我们结合您的示例会发生什么:

var name = "foo";

class AnythingYouLike {
  name = "bar";

  sayHello() {
    app.showMessage('Hello ' + this.name); // shows: Hello bar
    app.showMessage('Hello ' + name); // shows: Hello foo
  }
}

namethis.name 都是对两个不同值的有效引用。在 Java 中没有类似的结构可以抗衡。