第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

TypeScript 混入(Mixins)

混入(Mixins)是面向?qū)ο缶幊讨械囊粋€(gè)比較重要的概念。本節(jié)將會(huì)通過一個(gè)實(shí)例逐步介紹混入是如何在 TypeScript 中使用的。

1. 慕課解釋

在 TypeScript 中,可以根據(jù)不同的功能定義多個(gè)可復(fù)用的類,它們將作為 mixins。因?yàn)?extends 只支持繼承一個(gè)父類,我們可以通過 implements 來連接多個(gè) mixins,并且使用原型鏈連接子類的方法和父類的方法。

這就像組件拼合一樣,由一堆細(xì)粒度的 mixins 快速搭建起一個(gè)功能強(qiáng)大的類。

2. 簡(jiǎn)單的對(duì)象混入

先來看一個(gè)基礎(chǔ)例子:

let target = {  a: 1,  b: 1 }
let source1 = {  a: 2,  c: 3 }
let source2 = {  b: 2,  d: 4 }

Object.assign(target, source1, source2)

console.log(target) // { a: 2, b: 2, c: 3, d: 4 }

解釋: 通過 Object.assign()source1source2 混入到 target 上,并且替換了 target 對(duì)象原有的屬性值。

3. TypeScript Mixins

先介紹一個(gè)前置知識(shí): Object.getOwnPropertyNames() 方法返回一個(gè)由指定對(duì)象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol值作為名稱的屬性)組成的數(shù)組。

3.1 代碼演示

下面的代碼演示了如何在 TypeScript 中使用混入:

// Disposable Mixin
class Disposable {
  isDisposed!: boolean
  dispose() {
    this.isDisposed = true
  }
}

// Activatable Mixin
class Activatable {
  isActive!: boolean;
  activate() {
    this.isActive = true
  }
  deactivate() {
    this.isActive = false
  }
}

class SmartObject{
  constructor() {
    setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500)
  }

  interact() {
    this.activate()
  }

  // Disposable
  isDisposed: boolean = false
  dispose!: () => void
  // Activatable
  isActive: boolean = false
  activate!: () => void
  deactivate!: () => void
}
applyMixins(SmartObject, [Disposable, Activatable])

let smartObj = new SmartObject()
setTimeout(() => smartObj.interact(), 2000)

function applyMixins(derivedCtor: any, baseCtors: any[]) {
  baseCtors.forEach(baseCtor => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
      derivedCtor.prototype[name] = baseCtor.prototype[name]
    })
  })
}

3.2 逐步解析這個(gè)例子

代碼里首先定義了兩個(gè)類,它們將做為 mixins??梢钥吹矫總€(gè)類都只定義了一個(gè)特定的行為或功能。稍后我們使用它們來創(chuàng)建一個(gè)新類,同時(shí)具有這兩種功能。

// Disposable Mixin
class Disposable {
  isDisposed!: boolean
  dispose() {
    this.isDisposed = true
  }
}

// Activatable Mixin
class Activatable {
  isActive!: boolean
  activate() {
    this.isActive = true
  }
  deactivate() {
    this.isActive = false
  }
}

下面使用 implements 連接多個(gè)父類,需要在子類里實(shí)現(xiàn)所有接口定義。

class SmartObject implements Disposable, Activatable {}

這么做是為將要 mixin 進(jìn)來的屬性/方法創(chuàng)建出占位屬性。這告訴編譯器這些成員在運(yùn)行時(shí)是可用的,這樣就能使用 mixin 帶來的便利,雖說需要提前定義一些占位屬性。

  // Disposable
  isDisposed: boolean = false
  dispose!: () => void
  // Activatable
  isActive: boolean = false
  activate!: () => void
  deactivate!: () => void

子類對(duì)外暴露一個(gè)封裝后的 public 方法,方法的具體實(shí)現(xiàn)可以借助混入的 mixins 類中的屬性/方法:

  interact() {
    this.activate()
  }

最后,把 mixins 混入定義的類,完成全部實(shí)現(xiàn)部分。

applyMixins(SmartObject, [Disposable, Activatable])

applyMixins() 方法借助 Object.getOwnPropertyNames() 遍歷 mixins 上的所有屬性,并復(fù)制到目標(biāo)上去,把之前的占位屬性替換成真正的實(shí)現(xiàn)代碼。

function applyMixins(derivedCtor: any, baseCtors: any[]) {
  baseCtors.forEach(baseCtor => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
      derivedCtor.prototype[name] = baseCtor.prototype[name]
    })
  })
}

applyMixins() 這個(gè)工具函數(shù)可以封裝在項(xiàng)目中一個(gè)核心函數(shù)庫中。

4. 小結(jié)

混入這種思想在一些開源項(xiàng)目如 materialvue-class-component 中被廣泛使用,我們?nèi)粘9ぷ髦幸部梢愿鶕?jù)需求借鑒使用。