JS 回調模式

1. 回調示例

若是有個模塊 findeNodes() ,任務是找到指望的 DOM 元素並使用 hide() 處理:前端

function findNodes() {
    var i = 10000, nodes = [], found
    while (i--) {
        // ...複雜邏輯,篩選出符合的元素 found
        nodes.push(found)
    }
    return nodes
}

function hide(nodes) {
    for (let i = 0, max = nodes.length; i < max; i++) {
        nodes[i].style.display = 'none'
    }
}
hide(findNodes())

2. 改進

能夠看到函數 findNodes()hide() 分別兩次進行了循環,這是十分低效的,若是要避免這種重複循環,而且只要在 findNodes() 中選擇的時候就進行 hide() 那麼將是高效的實現方式。若是在 findNodes() 中實現修改邏輯,因爲檢索和修改邏輯耦合,那麼它將再也不是一個通用函數。對這種問題的解決方法是採用回調模式node

能夠將節點隱藏邏輯以回調函數的方式傳遞給 findNodes() 並委託執行:segmentfault

function findNodes(callback) {
    var i = 10000, nodes = [], found

    if (typeof callback !== 'function') {    // 檢查參數是否爲可調用
        callback = false
    }

    while (i--) {
        // ...複雜邏輯,篩選出符合的元素 found
        if (callback) {
            callback(found)
        }
        nodes.push(found)
    }
    return nodes
}

function hide(nodes) {
    nodes[i].style.display = 'none'
}

findNodes(hide)

那麼如今回調函數可選,重構後加入回調函數參數的 findNodes() 仍然能夠像之前同樣使用,而不會破壞舊 API 的原始代碼。緩存

3. 回調與做用域

前面的例子中,回調執行的語句:callback(para),在多數狀況下有效,可是若是傳遞的函數是對象的方法且有 this 那麼回調方法裏的 this 將指向的是全局對象,從而發生意外。微信

解決這個問題的方法是傳遞迴調函數,而且還傳遞該回調函數所屬的對象:ide

function findNodes (callback, callback_obj){
    ...
    if (typeof callback === 'function'){
        callback.call(callback_obj, found)
    }
    ...
}
findNodes (obj.sayName, obj)

固然,能夠把方法做爲字符串來傳遞,避免重複兩次輸入該對象的名稱:函數

findNodes (callback, callback_obj){
    if (typeof callback === 'string'){
        callback = callback_obj[callback]
    }
    if (typeof callback === 'function'){
        callback.call(callback_obj, found)
    }
}
findNodes('sayName', Obj)

本文是系列文章,能夠相互參考印證,共同進步~學習

  1. JS 抽象工廠模式
  2. JS 工廠模式
  3. JS 建造者模式
  4. JS 原型模式
  5. JS 單例模式
  6. JS 回調模式
  7. JS 外觀模式
  8. JS 適配器模式
  9. JS 利用高階函數實現函數緩存(備忘模式)
  10. JS 狀態模式
  11. JS 橋接模式
  12. JS 觀察者模式

網上的帖子大多深淺不一,甚至有些先後矛盾,在下的文章都是學習過程當中的總結,若是發現錯誤,歡迎留言指出~this

參考: <JavaScript 模式> P65

PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~spa

另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~

相關文章
相關標籤/搜索