2017-10-07 157 views
0

我有下面的代碼,它定義了輸入事件管理類:鼠標,觸摸,指針,...的Object.create繼承和初始化代碼

// base.js 
export default() => { 
    return { 
    el: undefined, 
    event: undefined, 
    handler(ev) { 
     console.log('default handler') 
    }, 
    attach() { 
     el.addEventListener(event, this.handler.bind(this), false) 
    }, 
    detach() { 
     el.removeEventListener(event, this.handler.bind(this), false) 
    } 
    } 
} 

// mouse.js 
import baseInput from './base' 

export default (el) => { 
    return Object.assign(Object.create(baseInput()), { 
    el: undefined, 
    event: 'mousedown', 
    handler(ev) { 
     console.log('mouse handler) 
    } 
    } 
} 

有一些共同的商業邏輯在「基地」對象。

的問題來自於attachdetach函數調用,因爲返回的約束功能是不是每次調用相同,因此removeEventListener不能刪除通過addEventListener添加的事件監聽器。

我知道我必須保持一個單一功能的參考。我的問題是代碼應該在哪裏。

一種解決方案可能是:

// base.js 
export default() => { 

    let boundFunction; 

    return { 
    el: undefined, 
    event: undefined, 
    getBoundFunction() { 
     if (!boundFunction) { 
     boundFunction = this.handler.bind(this) 
     } 
    }, 
    handler(ev) { 
     console.log('default handler') 
    }, 
    attach() { 
     el.addEventListener(event, this.getBoundFunction(), false) 
    }, 
    detach() { 
     el.removeEventListener(event, this.getBoundFunction(), false) 
    } 
    } 
} 

此代碼的工作,但我不希望額外getBoundFunction呼籲每個事件觸發,我覺得應該有一個更好的方法或最佳實踐。

+1

這是因爲你創建新的基礎對象,其所有屬性複製到一個新的對象做繼承,然後把它的方式很奇怪,有點浪費的方式。你爲什麼這樣做繼承?您可以使用新的屬性/方法擴展基礎對象,而不是複製並丟棄它。 – jfriend00

+0

在第一個代碼塊中必須存在拼寫錯誤,因爲在'mouse.js'中,有兩個連續的'return'語句。 – jfriend00

+0

是的。有一個錯字。謝謝。固定! – manelio

回答

3

通過改變handler名稱handleEvent實現事件監聽器接口。然後你直接綁定對象。

thishandleEvent函數的值將是綁定的對象。

// base.js 
export default() => { 
    return { 
    el: undefined, 
    event: undefined, 
    handleEvent(ev) { 
     console.log('default handler') 
    }, 
    attach() { 
     el.addEventListener(event, this, false) 
    }, 
    detach() { 
     el.removeEventListener(event, this, false) 
    } 
    } 
} 

所以後來從基礎對象繼承的對象可以定義自己的handleEvent功能,當綁定的事件觸發後調用。


另外,您似乎正在爲每個從它繼承的對象創建一個新的基礎對象。爲什麼不共享基礎對象?這是原型繼承的一點。

+2

這是一個很少使用的技巧。如果將對象傳遞給'addEventListener'和'removeEventListener',它會查找一個名爲'handleEvent'的特殊屬性名稱,並用原始對象的上下文對其進行調用。奇怪的,但工程。 – jfriend00

+0

@ jfriend00:你說得對。我認爲人們不知道它。它在統一業務邏輯和事件處理對象方面做得很好。使組織良好的代碼,國際海事組織。 – llama

+0

FWIW [對象如何可以實現在JavaScript Event接口(https://stackoverflow.com/questions/40353746/how-can-an-object-implements-the-event-interface-in-javascript/) – guest271314