国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS設計模式之Mixin(混入)模式

caiyongji / 3318人閱讀

摘要:概念模式就是一些提供能夠被一個或者一組子類簡單繼承功能的類意在重用其功能。示例下面通過一個簡單的例子來演示這個模式混入模式的實現不指定特定方法名的時候,將后者所有的方法都添加到前者里優缺點優點有助于減少系統中的重復功能及增加函數復用。

概念

Mixin模式就是一些提供能夠被一個或者一組子類簡單繼承功能的類,意在重用其功能。在面向對象的語言中,我們會通過接口繼承的方式來實現功能的復用。但是在javascript中,我們沒辦法通過接口繼承的方式,但是我們可以通過javascript特有的原型鏈屬性,將功能引用復制到原型鏈上,達到功能的注入。

示例

下面通過一個簡單的例子來演示這個模式

var Car = function(settings) {
  this.model = settings.model || "no model provided"
  this.color = settings.color || "no color provided"
}

var Mixin = function() {}

Mixin.prototype = {
  driveForward: function() {
    console.log("drive forward")
  },
  driveBackward: function() {
    console.log("drive backward")
  },
  driveSideways: function() {
    console.log("drive sideways")
  }
}

//混入模式的實現
function Merge(recClass, giveClass) {
  if(arguments.length > 2) {
    for(var i = 2, lenth = arguments.length; i < lenth ; ++ i) {
      var methodName = arguments[i]
      recClass.prototype[methodName] = giveClass.prototype[methodName]
    }
  }else {
    for(var methodName in giveClass.prototype) {
      if(!recClass.prototype[methodName]) {
        recClass.prototype[methodName] = giveClass.prototype[methodName]
      }
    }
  }
}

Merge(Car, Mixin, "driveForward", "driveBackward")

var myCar = new Car({
  model: "BMW",
  color: "blue"
})

myCar.driveForward()    //drive forward
myCar.driveBackward()   //drive backward

//不指定特定方法名的時候,將后者所有的方法都添加到前者里
Merge(Car, Mixin)

var mySportsCar = new Car({
  model: "Porsche",
  color: "red"
})

mySportsCar.driveForward()  //drive forward
優缺點

優點
有助于減少系統中的重復功能及增加函數復用。當一個應用程序可能需要在各種對象實例中共享行為時,我們可以通過在Mixin中維持這種共享功能并專注于僅實現系統中真正不同的功能,來輕松避免任何重復。

缺點
有些人認為將功能注入對象原型中會導致原型污染和函數起源方面的不確定性。

Vue混入功能研究

vue中關于混入的代碼目錄/src/core/global-api/mixin.js
可以看到vue源碼中是通過mergeOptions來合并配置到options上

export function initMixin (Vue: GlobalAPI) {
  Vue.mixin = function (mixin: Object) {
    this.options = mergeOptions(this.options, mixin)
    return this
  }
}

下面我們來看合并配置的相關代碼/src/core/instance/init.js
當執行new Vue的時候options._isComponent為false,會走else的分支

export function initMixin (Vue: Class) {
  Vue.prototype._init = function (options?: Object) {
    const vm: Component = this
    // a uid
    vm._uid = uid++

    let startTag, endTag
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== "production" && config.performance && mark) {
      startTag = `vue-perf-start:${vm._uid}`
      endTag = `vue-perf-end:${vm._uid}`
      mark(startTag)
    }

    // a flag to avoid this being observed
    vm._isVue = true
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options)
    } else {
      vm.$options = mergeOptions(  //合并配置
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      )
    }
    /* istanbul ignore else */
    if (process.env.NODE_ENV !== "production") {
      initProxy(vm)
    } else {
      vm._renderProxy = vm
    }
    // expose real self
    vm._self = vm
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, "beforeCreate")
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, "created")

    /* istanbul ignore if */
    if (process.env.NODE_ENV !== "production" && config.performance && mark) {
      vm._name = formatComponentName(vm, false)
      mark(endTag)
      measure(`vue ${vm._name} init`, startTag, endTag)
    }

    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

下面來看mergeOptions的實現src/core/util/options.js
mergeField將this.options(parent)和需要混入的對象mixin(child)合并在this.options上面

/**
 * Merge two option objects into a new one.
 * Core utility used in both instantiation and inheritance.
 */
export function mergeOptions (
  parent: Object,
  child: Object,
  vm?: Component
): Object {
  if (process.env.NODE_ENV !== "production") {
    checkComponents(child)
  }

  if (typeof child === "function") {
    child = child.options
  }

  normalizeProps(child, vm)
  normalizeInject(child, vm)
  normalizeDirectives(child)
  const extendsFrom = child.extends
  if (extendsFrom) {
    parent = mergeOptions(parent, extendsFrom, vm)
  }
  if (child.mixins) {
    for (let i = 0, l = child.mixins.length; i < l; i++) {
      parent = mergeOptions(parent, child.mixins[i], vm)
    }
  }
  const options = {}
  let key
  for (key in parent) {
    mergeField(key)
  }
  for (key in child) {
    if (!hasOwn(parent, key)) {
      mergeField(key)
    }
  }
  function mergeField (key) {
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
  return options
}
參考

《JavaScript設計模式》

JS設計模式系列文章

JS設計模式之Obeserver(觀察者)模式、Publish/Subscribe(發布/訂閱)模式
JS設計模式之Factory(工廠)模式
JS設計模式之Singleton(單例)模式
JS設計模式之Facade(外觀)模式
JS設計模式之Module(模塊)模式、Revealing Module(揭示模塊)模式
JS設計模式之Mixin(混入)模式

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103895.html

相關文章

  • mixin混入邏輯

    摘要:現在有一個需求,將沒有而有的屬性混入到中。有而且也有的屬性不混入以為準。通過這種混入機制滾雪球的方式可以不斷地擴充一個對象地的功能。暫且將它定義為混入模式。混入模式是構建復雜對象的一種常用的模式。 有A對象和B對象,A, B對象有有方法屬性和數據屬性。現在有一個需求,將A沒有而B有的屬性混入到A中。A有而且B也有的屬性不混入以A為準。通過這種混入機制(滾雪球的方式)可以不斷地擴充一個對...

    hufeng 評論0 收藏0
  • 高級 Vue 組件模式 (4)

    摘要:使用替換目標在第三篇文章中,我們使用來抽離了注入依賴項的公共邏輯。成果通過作用域插槽,我們有效地避免了第三方組件由于混入而可能造成的命名沖突以及隱式依賴等問題。 04 使用 slot 替換 mixin 目標 在第三篇文章中,我們使用 mixin 來抽離了注入 toggle 依賴項的公共邏輯。在 react 中,類似的需求是通過 HOC 的方式來解決的,但是仔細想想的話,react 在早...

    LancerComet 評論0 收藏0
  • 高級 Vue 組件模式 (3)

    摘要:在中,我們是否也有一些手段或特性來提高組件的復用程度和靈活性呢答案當然是有的,那就是。成果通過實現,我們成功將注入的邏輯抽離了出來,這樣每次需要共享組件的狀態和方法時,混入該即可。 03 使用 mixin 來增強 Vue 組件 目標 之前一篇文章中,我們雖然將 toggle 組件劃分為了 toggle-button、toggle-on 和 toggle-off 三個子組件,且一切運行良...

    iKcamp 評論0 收藏0
  • 從裝飾模式到裝飾器

    摘要:從裝飾模式到裝飾器裝飾模式裝飾模式的作用是在不修改原有的接口的情況下,讓類表現的更好。它是一個語法糖說完了裝飾模式,我們再看一下在中最新引入的裝飾器。 從裝飾模式到裝飾器 裝飾模式 裝飾模式的作用是:在不修改原有的接口的情況下,讓類表現的更好。 什么叫更好? 為什么需要裝飾模式 自然是繼承有一些問題繼承會導致超類和子類之間存在強耦合性,當超類改變時,子類也會隨之改變; 超類的內...

    monw3c 評論0 收藏0
  • 如何正確的(?)利用 Vue.mixin() 偷懶

    摘要:前言最近開發的頁面以及功能大都以表格為主,接口獲取來的數據大都是需要經過處理,比如時間戳需要轉換,或者狀態碼的轉義。首先,還是在文件中定義一個狀態碼對應對象,這里我們將其對應的內容設為段落。 前言 最近開發的頁面以及功能大都以表格為主,接口獲取來的 JSON 數據大都是需要經過處理,比如時間戳需要轉換,或者狀態碼的轉義。對于這樣的問題,各大主流框架都提供了類似于過濾的方法,在 Vue ...

    Leo_chen 評論0 收藏0

發表評論

0條評論

caiyongji

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<