本文章記錄本人在學習 JavaScript 中看書理解到的一些東西,加深記憶和而且整理記錄下來,方便以後的複習。node
在js
裏函數都是對象,這表示它們能夠做爲參數傳遞給其餘的函數。舉例:當函數b()
做爲參數傳遞給函數a()
,那麼在某一時刻函數a()
可能會執行或者調用函數b()
。這種狀況下,函數b()
就被稱爲回調函數,也能夠簡稱叫作回調(下面是栗子)。數組
JavaScript'use strict'; function a(callback) { callback(); } function b() { console.log('hello callback'); } a(b); // 注意 b() 做爲參數傳遞給 a() 的時候是不須要帶括號的
假設有一個通用的函數執行一些複雜的處理工做,而且返回結果爲一個大塊數據(下面是栗子)。app
JavaScriptvar findeNodes = function () { var i = 10000, node = [], found; while (i) { i -= 1; node.push(found); } return nodes; }
上面代碼定義函數findNodes()
,它的任務是抓取頁面的dom tree
,並返回一個你要的頁面元素數組。dom
在定義一個函數hide()
,顧名思義它的做用是隱藏頁面中的節點(下面是栗子)。ide
JavaScriptvar hide = function (nodes) { for (var i = 0; i < nodes.length; i += 1) { nodes[i].style.display = 'block'; } } // 執行函數 hide(findeNodes());
好了,要的效果都實現了,可是實現倒是低效的。由於hide()
必須再次循環由findNodes()
返回的數組節點。若是能避免這種循環,只須要在findNodes()
中選擇即可隱藏節點,那麼這將是更高效的方式。可是若是在findNodes()
中實現隱藏邏輯的話,因爲檢索和修改邏輯耦合,那麼他再也不是通用的函數。面對這種問題的解決方法是採用回調模式,能夠將所以節點邏輯以回調函數方式傳遞給findNodes()
並委託執行(下面是栗子)。函數
JavaScript// 重構 findeNodes() 函數,並接受一個回調函數 var findeNodes = function (callback) { var i = 10000, nodes = [], found; while (i) { i -= 1; // 如今運行回調函數 if (typof callback === 'function') { callback(); } nodes.push(found); } return found; }
上面的代碼只是作了對callback
是否存在進行了判斷,若是存在的話嗎,那麼就執行該函數。其中,回調函數是可選的,所以後續的findeNodes()
仍然能夠想之前同樣使用,而不會破壞以來舊API
的原始代碼。學習
如今hide
的實現就簡單多了,由於它不須要再去循環遍歷全部的節點了(下面是栗子)。this
JavaScript// 回調函數 var hide = function (nodes) { nodes.style.display = 'none'; } // 找到指定的節點,並在後續執行中隱藏 findeNodes(hide);
在上一個栗子中,回調函數執行的語句是這樣的:callback(parameters)
。code
雖然上面那句在大多數的場景上都是有效的,可是總會有一些場景,其回調函數並非一次性的匿名函數或者全局函數,而是對象的方法。若是該函數使用this
來引用它所的屬性,這可能有是一個坑了(下面是栗子)。對象
JavaScript// 假設回調函數是 paint(),它是一個名爲 myapp 的對象的方法 var myapp = {}; myapp.color = 'green'; myapp.paint = function (nodes) { nodes.style.color = this.color; } // 而後用到上一個栗子的 findeNodes() findeNodes(myapp.paint); //
坑:this.color
沒有被定義,由於findeNods()
是一個全局函數,所以,對象的this
是指向window
的。
解決的方法有:
findNodes()
函數(下面是栗子)。JavaScriptvar findNodes = function (callback, callback_obj) { // ... if (typof callback === 'function') { callback.call(callback_obj, found); } // ... } // 執行函數 findNodes(myapp.paint, myapp);
主要是經過call、apply
來修改函數運行時的this
指向。
JavaScriptvar findNodes = function (callback, callback_obj) { // ... if (typof callback === 'string') { callback = callback_obj[callback]; } // ... if (typof callback === 'function') { callback.call(callback_obj, found); } // ... } // 執行函數 findNodes('paint', myapp);
最後,若是文章有什麼錯誤和疑問的地方,請指出。與sf各位共勉!