iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
Modern Web

Angular,啟動。系列 第 24

Day24-TypeScipt: 存取器get&set

  • 分享至 

  • xImage
  •  

存取器 (Getter & Setter)簡介

透過存取器可以更靈活的制物件屬性,在不同語言中都擁有類似的模式;本文介紹在 TypeScriptAngular 實務上是如何使用存取器。

特性

  • 對私有屬性進行間接操作,提高安全性。
  • Getter 是透過 funtion 模擬呼叫物件屬性時的行為。
  • Setter 是透過 funtion 模擬賦值到物件屬性的行為。
  • 有 Getter 無 Setter = 唯讀 Readonly。
  • Getter 不能有參數、且要有回傳值。
  • Setter 只能有一個參數。

TypeScript 中的 Getter & Setter

※編譯器輸出的 JS 需要 ES5 以上。

// 1.設定一個產品類別
export class Product {
  public id: string;
  public name: string;
  private _price: number; // 此為私有屬性(通常會+底線)
}

// 2.建立新的實例
let book = new Product();
// 3.設定序號、名稱、價格
book.id = "1";
book.name = "A_Book";
book._price = 100; //! 報錯 不能從外部訪問

為了解決不能使用私有屬性的問題,使用了存取器。

export class Product {
  public id: string;
  public name: string;
  private _price: number;
  
  public get price() {          // 模擬呼叫
    return this._price
  }
  public set price(v: number) { // 模擬賦值
    this._price = v
  }
}

let book = new Product();
book.id = "1";
book.name = "A_Book";
book.price = 100; // 成功:D
// 調用的其實不是私有屬性,而是同名的 getter,
// 然後 getter 傳回私有屬性的值。

額外應用:於 Setter 賦值時增加邏輯判斷

export class Product {
  public id: string;
  public name: string;
  private _price: number;

  public get price() { 
    return this._price
  }
  public set price(v: number) { 
    if(v===0){
      console.log("Error.價格不得為0");
    } else {
	  this._price = v
    }
  }
}

let book = new Product();
book.id = "1";
book.name = "A_Book";
book.price = 0; //! Error.價格不得為0

Angular 中的 Getter & Setter

Angular 中存取器經常用於屬性更改、父組件傳值給子組件的方法。

父組件:Parent、子組件:Product

<app-product [name]="book" [price]="100"></app-product>
export class ProductComponent {
  public id: string;
  private _name: string;
  private _price: number;

  // 1.價格存取器
  @Input
  public get price() { 
    return this._price
  }
  public set price(v: number) { 
    this._price = v
  }

  // 2.名稱存取器
  @Input
  public get name() { 
    return this._name
  }
  public set price(v: string) { 
    this._name = v
  }
}
<!--book-->
<p>{{name}}</p>

每當父組件更改屬性時,子組件 setter 就會被觸發。
也可像上面介紹 TypeScript 存取器篇章中,在 Input setter 設置邏輯判斷,不過有一些限制:

  1. 不要在 setter 使用 side effects。

    副作用(side effects):如修改其他屬性的值、觸發某些事件,可能導致程式行為出現變化。

  2. 不要在 setter 使用 subscription(訂閱器)

  3. 不要在 setter 使用 changeDetector.detectChanges(),請改使用 changeDetector.markForCheck()

參考來源

TypeScript | 從 TS 開始學習物件導向 - Class 用法
Using Getters and Setters in TypeScript and Angular
【Day 23】TypeScript - 類別存取器(Accessors)


上一篇
Day23-css 選擇器-3: 複合選擇器
下一篇
Day25-TypeScipt: 關於類別(Class) 與物件(Object)
系列文
Angular,啟動。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言