TypeScript

TypeScript 物件中的 public, private, protected, static, readonly

TypeScript 中的 class 可以為屬性加上 5 種前綴來決定存取該屬性的權限 — public ( default ), private, static, protected, readonly,簡單筆記一下 5 種前綴的存取權。

1. Public

  1. 如果沒有在屬性前加上任何前綴,那麼 TypeScript 會預設這個屬性是 public 。
  2. 要存取 class 裡的屬性,請先記得 new 一個 instance ,否則就算將屬性設置為 public ,也無法直接從 class 存取到屬性。
class Property {
  public firstName: string;
  height: number;

  constructor() {
    this.firstName = 'Jimmy';
    this.height = 180
  }
}

const propertyInstance = new Property();
console.log(Property.firstName);
// Property 'firstName' does not exist on type 'typeof Property'.
console.log(propertyInstance.name);
// 'Jimmy'
console.log(Property.height);
// Property 'height' does not exist on type 'typeof Property'.
console.log(propertyInstance.height);
// 180

2. Private

  1. private 是 TypeScript 提供的屬性前綴,要在 JavaScript 中產生類似的效果,只要在屬性名稱前加上’#’即可,ex: #_name。
  2. private 代表屬性是 class 私有的,只有在 class 內部才存取的到,從外部直接存取 class 本體的 private 屬性,或是 new 一個 instance 存取 private 屬性都會有 error。
  3. 要從外部存取 private 屬性的方法只能寫一個 getter 或是 function 來回傳內部的 private 屬性。要注意的是 getter 只能 new instance 後呼叫,不能直接從 class 本體呼叫。
class Property {
  // 一般來說習慣將 private 的屬性加上_,標示為 private
  private _age: number;

  constructor() {
    this._age = 18;
  }
  
  get get_age() {
    return this._age;
  }
}

const propertyInstance = new Property();
console.log(Property._age);
// Error!! Property '_age' is private and only accessible within class 'Property'.
console.log(propertyInstance._age);
// Error!! Property '_age' is private and only accessible within class 'Property'.
console.log(Property.get_age)
// Error!! Property 'get_age' does not exist on type 'typeof Property'.
console.log(propertyInstance.get_age);
// 18

3. Protected

  1. 在屬性前面加上 protected 後只有 class 內部和繼承該 class 的 子class 可以存取的到該屬性。
  2. 在 子class 內部可以直接用 this.[屬性] 存取到 父class 的 protected 屬性。
  3. protected 屬性無法在外部直接從 class 本體或是 instance 存取。
class Property {
  protected address: string;

  constructor() {
    this.address = 'Taipei';
  }
}

class PropertyChild extends Property {
  getAddress() {
    return this.address;
  }
}

const propertyInstance = new Property();
const propertyChild = new PropertyChild();
console.log(Property.address);
// Error!! Property 'address' does not exist on type 'typeof Property'.
console.log(propertyInstance.address);
// Error!! Property 'address' is protected and only accessible within class 'Property' and its subclasses.
console.log(PropertyChild.address);
// Error!! Property 'address' does not exist on type 'typeof Property'.
console.log(propertyChild.address);
// Error!! Property 'address' is protected and only accessible within class 'Property' and its subclasses.

console.log(propertyChild.getAddress());
// 'Taipei'

4. Static

  1. 加上 static 的屬性只能直接從 class 本體存取,不能 new instance 後再用 instance 存取。
  2. 加上 static 的屬性在 class 內部要使用的話要用 [class name].[static 屬性]來存取,而不是 public 或 private 的 this.[屬性] 。
  3. 加上 static 的 function 一樣只能直接用 class 本體存取。
class Property {
  static age: number;

  constructor() {
    Property.age = 18;
  }

  static staticFunction() {
    return 'staticFunction works!!'
  };
}

const propertyInstance = new Property();
console.log(Property.age);
// 18
console.log(propertyInstance.age);
// Error!! Property 'age' does not exist on type 'Property'.
console.log(Property.staticFunction());
// 'staticFunction works!!'
console.log(propertyInstance.staticFunction);
// Error!! Property 'staticFunction' does not exist on type 'Property'.

5. ReadOnly

  • readonly 的屬性只能存取不能修改。
  • readonly 也可以用在 interface 中。
// 用在 class
class Employee {
  readonly empCode: number;
  empName: string;
  
  constructor(code: number, name: string)     {
      this.empCode = code;
      this.empName = name;
  }
}

const employee = new Employee(101, 'Jimmy');
employee.empCode = 102;
// Error!! Cannot assign to 'empCode' because it is a read-only property.

// 用在 interface
interface IEmployee {
  empCode: number;
  empName: string;
}

let emp1: Readonly<IEmployee> = {
  empCode:1,
  empName:"Steve"
}

emp1.empCode = 100;
// Compiler Error: Cannot assign to 'empCode' because it is a read-only property.
emp1.empName = 'Bill';
// Compiler Error: Cannot assign to 'empCode' because it is a read-only property.

let emp2: IEmployee = {
  empCode:1,
  empName:"Steve"
}

emp2.empCode = 100; // OK
emp2.empName = 'Bill'; // OK

6. 參考資料

TypeScript Data Modifiers: public, private, protected, static, readonly

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top