<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                請注意:本書已遷移至獨立站點,請移步訪問:[前端面試寶典](https://www.mianshibook.com/) 設計模式總的來說是一個抽象的概念,前人通過無數次的實踐總結出的一套寫代碼的方式,通過這種方式寫的代碼可以讓別人更加容易閱讀、維護以及復用。 這里我們將來學習幾種最常用的設計模式。 ## 工廠模式 工廠模式分為好幾種,這里就不一一講解了,以下是一個簡單工廠模式的例子 ~~~ class Man { constructor(name) { this.name = name } alertName() { alert(this.name) } } class Factory { static create(name) { return new Man(name) } } Factory.create('yck').alertName() ~~~ 當然工廠模式并不僅僅是用來 new 出**實例**。 可以想象一個場景。假設有一份很復雜的代碼需要用戶去調用,但是用戶并不關心這些復雜的代碼,只需要你提供給我一個接口去調用,用戶只負責傳遞需要的參數,至于這些參數怎么使用,內部有什么邏輯是不關心的,只需要你最后返回我一個實例。這個構造過程就是工廠。 工廠起到的作用就是隱藏了創建實例的復雜度,只需要提供一個接口,簡單清晰。 在 Vue 源碼中,你也可以看到工廠模式的使用,比如創建異步組件 ~~~ export function createComponent ( Ctor: Class<Component> | Function | Object | void, data: ?VNodeData, context: Component, children: ?Array<VNode>, tag?: string ): VNode | Array<VNode> | void { // 邏輯處理... const vnode = new VNode( `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`, data, undefined, undefined, undefined, context, { Ctor, propsData, listeners, tag, children }, asyncFactory ) return vnode } ~~~ 在上述代碼中,我們可以看到我們只需要調用`createComponent`傳入參數就能創建一個組件實例,但是創建這個實例是很復雜的一個過程,工廠幫助我們隱藏了這個復雜的過程,只需要一句代碼調用就能實現功能。 ## 單例模式 單例模式很常用,比如全局緩存、全局狀態管理等等這些只需要一個對象,就可以使用單例模式。 單例模式的核心就是保證全局只有一個對象可以訪問。因為 JS 是門無類的語言,所以別的語言實現單例的方式并不能套入 JS 中,我們只需要用一個變量確保實例只創建一次就行,以下是如何實現單例模式的例子 ~~~ class Singleton { constructor() {} } Singleton.getInstance = (function() { let instance return function() { if (!instance) { instance = new Singleton() } return instance } })() let s1 = Singleton.getInstance() let s2 = Singleton.getInstance() console.log(s1 === s2) // true ~~~ 在 Vuex 源碼中,你也可以看到單例模式的使用,雖然它的實現方式不大一樣,通過一個外部變量來控制只安裝一次 Vuex ~~~ let Vue // bind on install export function install (_Vue) { if (Vue && _Vue === Vue) { // 如果發現 Vue 有值,就不重新創建實例了 return } Vue = _Vue applyMixin(Vue) } ~~~ ## 適配器模式 適配器用來解決兩個接口不兼容的情況,不需要改變已有的接口,通過包裝一層的方式實現兩個接口的正常協作。 以下是如何實現適配器模式的例子 ~~~ class Plug { getName() { return '港版插頭' } } class Target { constructor() { this.plug = new Plug() } getName() { return this.plug.getName() + ' 適配器轉二腳插頭' } } let target = new Target() target.getName() // 港版插頭 適配器轉二腳插頭 ~~~ 在 Vue 中,我們其實經常使用到適配器模式。比如父組件傳遞給子組件一個時間戳屬性,組件內部需要將時間戳轉為正常的日期顯示,一般會使用`computed`來做轉換這件事情,這個過程就使用到了適配器模式。 ## 裝飾模式 裝飾模式不需要改變已有的接口,作用是給對象添加功能。就像我們經常需要給手機戴個保護套防摔一樣,不改變手機自身,給手機添加了保護套提供防摔功能。 以下是如何實現裝飾模式的例子,使用了 ES7 中的裝飾器語法 ~~~ function readonly(target, key, descriptor) { descriptor.writable = false return descriptor } class Test { @readonly name = 'yck' } let t = new Test() t.yck = '111' // 不可修改 ~~~ 在 React 中,裝飾模式其實隨處可見 ~~~ import { connect } from 'react-redux' class MyComponent extends React.Component { // ... } export default connect(mapStateToProps)(MyComponent) ~~~ ## 代理模式 代理是為了控制對對象的訪問,不讓外部直接訪問到對象。在現實生活中,也有很多代理的場景。比如你需要買一件國外的產品,這時候你可以通過代購來購買產品。 在實際代碼中其實代理的場景很多,也就不舉框架中的例子了,比如事件代理就用到了代理模式。 ~~~ <ul id="ul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <script> let ul = document.querySelector('#ul') ul.addEventListener('click', (event) => { console.log(event.target); }) </script> ~~~ 因為存在太多的`li`,不可能每個都去綁定事件。這時候可以通過給父節點綁定一個事件,讓父節點作為代理去拿到真實點擊的節點。 ## 發布-訂閱模式 發布-訂閱模式也叫做觀察者模式。通過一對一或者一對多的依賴關系,當對象發生改變時,訂閱方都會收到通知。在現實生活中,也有很多類似場景,比如我需要在購物網站上購買一個產品,但是發現該產品目前處于缺貨狀態,這時候我可以點擊有貨通知的按鈕,讓網站在產品有貨的時候通過短信通知我。 在實際代碼中其實發布-訂閱模式也很常見,比如我們點擊一個按鈕觸發了點擊事件就是使用了該模式 ~~~ <ul id="ul"></ul> <script> let ul = document.querySelector('#ul') ul.addEventListener('click', (event) => { console.log(event.target); }) </script> ~~~ 在 Vue 中,如何實現響應式也是使用了該模式。對于需要實現響應式的對象來說,在`get`的時候會進行依賴收集,當改變了對象的屬性時,就會觸發派發更新。 ## 外觀模式 外觀模式提供了一個接口,隱藏了內部的邏輯,更加方便外部調用。 舉個例子來說,我們現在需要實現一個兼容多種瀏覽器的添加事件方法 ~~~ function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture) return true } else if (elm.attachEvent) { var r = elm.attachEvent("on" + evType, fn) return r } else { elm["on" + evType] = fn } } ~~~ 對于不同的瀏覽器,添加事件的方式可能會存在兼容問題。如果每次都需要去這樣寫一遍的話肯定是不能接受的,所以我們將這些判斷邏輯統一封裝在一個接口中,外部需要添加事件只需要調用`addEvent`即可。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看