21

在 C++ 中有一种叫做友元类的东西。据我所知,TypeScript/JavaScript 中没有这样的东西。有没有办法在 TypeScript/JavaScript 中模拟朋友类的这种行为?

为了提供更好的背景(如果需要)我为什么以及我尝试做什么,我制作了一些小游戏来娱乐(和学习东西)并尝试这样。目前我只使用公共方法并且一切正常,但我想将这些方法的可访问性限制为仅另一个类。如果有帮助,我会使用 TypeScript。

4

2 回答 2

24

TypeScript 仅提供protectedprivate访问修饰符。它目前没有类似friendor的东西internal


要获得类似的效果:如果您将代码打包为库并为其发出.d.ts声明文件,则可以/** @internal */在不希望外人使用的属性上使用 JSDoc 注释,同时指定--stripInternal 编译器选项。这将导致导出的声明忽略这些属性。


做类似事情的另一种方法是提出一个interface您的类实现的公共,然后只将该类导出为公共接口。例如:

// public interfaces
export interface UnitStatic {
  new(grid: Grid, x: number, y: number): Unit;
}
export interface Unit {
  move(x: number, y: number): void;
}
export interface GridStatic {
  new(): Grid;
  NUM_CELLS: number;
  CELL_SIZE: number; 
}
export interface Grid {
  // public methods on Grid
}

// private implementations
class UnitImpl implements Unit {
  constructor(private grid: GridImpl, private x: number, private y: number) {

  }
  move(x: number, y: number) {
    // ...
  }
}

class GridImpl implements Grid {
  cells: Unit[][] = [];
  constructor() {
    // ...
  }
  static NUM_CELLS = 10;
  static CELL_SIZE = 20;
}

//public exports
export const Unit: UnitStatic = UnitImpl;
export const Grid: GridStatic = GridImpl;

这很乏味,但可以非常明确地说明您的代码的哪些部分是为外人设计的,哪些不是。


或者,由于以上都没有真正阻止人们在运行时访问 JavaScript 中的私有/内部信息,你可以使用IIFE真正向外界隐藏这些东西。不过,这在 TypeScript 中可能会更烦人,因为它可能需要您创建上述公共接口才能正确地进行类型检查。


因此,您有一些选择。希望他们有所帮助。祝你好运!

于 2017-08-23T21:38:32.173 回答
-9

嗯,当然是提议的。请参阅https://github.com/Microsoft/TypeScript/issues/2136

但归根结底,TypeScript 不是 C++,也不是 Java。是的,TypeScript(和 ES6)提供了类,这有点像经典 OOP 语言中的类,但该语言并不是真正打算成为具有所有 OOP 风吹草动的成熟 OOP 语言,也不应该是。

如果你发现自己想要朋友类,你应该考虑你过度设计你的类层次结构并将太多的设计逻辑放入类结构中的可能性,试图将 JS/TS 变成一种 OOP 语言,它从来没有打算成为.

于 2017-08-23T19:16:10.327 回答