默认的控制权限是 public.public 属性的字段和方法,可以在 class 外部被访问。
class MySafe { private secretKey = 12345; } Try // In a JavaScript file... const s = new MySafe(); // Will print 12345 console.log(s.secretKey);
因为 public 已经是默认的可见性修饰符,所以你不需要将它写在类成员上,但可能出于样式/可读性原因选择这样做。
protected
受保护的成员仅对声明它们的类的子类可见。
Exposure of protected members
派生类需要遵循其基类契约,但可以选择公开具有更多功能的基类子类型。 这包括公开受保护的成员:
class Base { protected m = 10; } class Derived extends Base { // No modifier, so default is 'public' m = 15; } const d = new Derived(); console.log(d.m); // OK
请注意,Derived 已经能够自由地读取和写入 m,因此这不会有意义地改变这种情况的“安全性”。 这里要注意的主要事情是,在派生类中,如果这种暴露不是故意的,我们需要小心地重复受保护的修饰符。
private
private 类似于 protected,但不允许从子类访问成员:
上述例子表明我们不能在子类里将父类的 private 属性提升成 protected 或者 public.
子类也无法访问父类的 private 字段。
Cross-instance private access
在 TypeScript 类实例内部,一个实例能访问其他实例的私有字段吗?答案是可以。
c
class A { private x = 10; public sameAs(other: A) { // No error return other.x === this.x; } }
TypeScript class 访问控制的镜花水月
与 TypeScript 类型系统的其他方面一样,private 和 protected 仅在类型检查期间强制执行。 这意味着 JavaScript 运行时构造(如 in 或简单属性查找)仍然可以访问私有或受保护成员。
class MySafe { private secretKey = 12345; } Try // In a JavaScript file... const s = new MySafe(); // Will print 12345 console.log(s.secretKey);
上面这段 TypeScript 代码虽然有语法错误,但是编译成 JavaScript 之后,仍然能够成功执行,访问到 s 的 secretKey 字段。