81

是否可以在 TypeScript 类中创建私有“函数”(方法)?假设我们有以下Person.tsTypeScript 文件:

class Person {
    constructor(public firstName: string, public lastName: string) {
    }

    public shout(phrase: string) {
        alert(phrase);
    }

    private whisper(phrase: string) {
        console.log(phrase);
    }
}

编译时将转换为以下内容:

var Person = (function () {
    function Person(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    Person.prototype.shout = function (phrase) {
        alert(phrase);
    };
    Person.prototype.whisper = function (phrase) {
        console.log(phrase);
    };
    return Person;
})();

观察

我期待whisper函数在闭包中声明,而不是在原型上?本质上,这会使whisper函数在编译时公开?

4

3 回答 3

93

TypeScript 公共/私有关键字仅适用于 TypeScript 检查代码的方式——它们对 JavaScript 输出没有任何影响。

根据语言规范(第 9-10 页):

私有可见性是一种设计时构造;它在静态类型检查期间强制执行,但并不意味着任何运行时强制执行。... TypeScript 在设计时强制封装类中的实现(通过限制私有成员的使用),但不能在运行时强制封装,因为所有对象属性都可以在运行时访问。JavaScript 的未来版本可能会提供私有名称,这将启用私有成员的运行时强制执行

这已经在这里被询问和回答:https ://stackoverflow.com/a/12713869/1014822

更新:这个旧的答案仍然有大量的流量,所以值得注意的是,除了上面的语言规范链接之外,公共、私有和(现在)受保护的成员在 TypeScript手册关于类的章节中有详细介绍。

ES 私有字段的2018 更新 实现现在是 TypeScript 路线图中的未来项目,尽管讨论表明这将是一个并行的硬私有选项,而不是替代当前的软私有实现。

自 TS 3.8 起,使用运算符的2020 更新 运行时私有字段#已实施。有一个很好的讨论它们是如何工作的,以及它们与编译时字段有何不同,这里private有StackOverflow 上的关键字。

私有方法已达到 TC39 工作组的第 3 阶段。该功能目前正在针对 TypeScript 进行积极讨论,例如此处

于 2013-06-04T14:01:34.217 回答
11

在 Javascript(与 TypeScript 相对)中,您不能拥有私有的“成员”函数。

如果你在闭包中定义了一个私有函数,你将不能在你的类的实例上调用它作为实例方法。

如果这是您想要的,只需将 TypeScript 函数定义移到类主体之外。

于 2013-06-04T13:43:24.997 回答
1

您可以在 TypeScript/Webpack 甚至最新的 Google Chrome 本地版本中使用私有类变量和函数。只需#在名称前添加一个。见这里

MyClass {

  #privateMember: Number = 4 

  #privateMethod() {
      this.#privateMember = 3
  }
}
于 2020-04-24T09:35:48.383 回答