若是有個模塊 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())
能夠看到函數 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 的原始代碼。緩存
前面的例子中,回調執行的語句: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)
本文是系列文章,能夠相互參考印證,共同進步~學習
網上的帖子大多深淺不一,甚至有些先後矛盾,在下的文章都是學習過程當中的總結,若是發現錯誤,歡迎留言指出~this
參考: <JavaScript 模式> P65
PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~spa
另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~