iT邦幫忙

0

ES6 Class / Symbol

大綱

  • 物件列舉屬性 (for-in/Object.keys)
  • 物件屬性特性設定 (ES5 defineProperty / ES6 Symbol)
  • ES6 Class static / getter / setter

物件 列舉屬性

  • Object.keys(obj) 列舉屬性
  • for-in 迴圈列舉原型鏈上的屬性
  const obj = {
    name: 'John',
    age: 30,
  }
  obj.isRead = true

  // 列舉屬性
  Object.keys(obj) // ['name','age','isRead']

  // for-in 迴圈 會列舉出包含在原型鏈中的所有屬性
  // ESLint 不建議使用此
  for (const key in obj) {
    // 是否為該物件的屬性,而非原型鏈的
    if (obj.hasOwnProperty(key)) {
      const elem = object[key]
      console.log(elem)
    }
  }

物件 屬性特性設定

  • Object.defineProperty 設定屬性特性
  • ES6 Symbol 無法被 for-in 或 Object.keys 列舉
  // ES5 屬性不被列舉的寫法
  // 設定屬性特性 (是否唯獨、可被列舉、更改...等)
  Object.defineProperty(obj, 'isRead', {
    value: true,
    writable: true, // 是否可更改屬性
    enumerable: false, // 使其無法列舉
  })

  // 取得該屬性的特性
  Object.getOwnPropertyDescriptor(obj, '屬性名')
  const isRead = Symbol()
  const obj = {
    name: 'John',
    age: 30
  }
  obj[isRead] = true
  console.log(obj) // {name: 'John', age: 30, Symbol(): true }

ES6 static/get/set

ES6 Static 用法

  • 靜態方法不須實例化,即可被呼叫
  • 但被實例化後,則靜態方法不能被呼叫 (私有方法)
  • 常用於工具函式 (資料處理)
  class Calculator {
    constructor(str) { this.str = str }
    static add(a, b) { console.log(a + b) }
    hey() { return this.str }
  }

  const calculatorA = new Calculator('hey')
  // 建立實體後,無法透過實體使用該函式
  console.log(calculatorA.add) // undefined
  console.log(calculatorA.hey()) // 'hey'

  // 沒有建立實體即可使用
  Calculator.add(1, 4) // 3

ES6 get/set 用法 (僅用於私有屬性)

  • 可控制 資料 寫入 & 讀出的過程
  • 可於中間作一些格式處理、錯誤偵測
  • getter不會有傳入參數,setter只會有一個傳入參數
  • 範例參考於此
  class Option {
    constructor(key, value) {
      if (typeof key !== 'undefined') { this[`_${key}`] = value }
    }
    get color() {
      if (this._color !== undefined) { return this._color } 
      return 'no color prop'
    }
    set color(value) { this._color = value }
  }

  const op1 = new Option('color', 'red')
  op1.color = 'yellow'

  const op2 = new Option('action', 'run')
  op2.color = 'yellow'

ES5 getter / setter 寫法

  • 使用 Object.defineProperty
  • 若要使物件的屬性無法被更動 writable: false,
  Object.defineProperty(obj, 'key', {
    get() {
      // 取得值前 可於此作format....etc
      return this.name
    },
    set(val) {
      // 設定值前可以作一些 例外判斷 (falsy...etc)
      this.name = val
      console.log(val)
    },
  })

尚未有邦友留言

立即登入留言