函数就是对象,所以他们可以作为一个参数传递给其它函数;
当你将introduceBugs()作为一个参数传递给writeCode(),然后在某个时间点,writeCode()有可能执行(调用)introduceBugs();
这种情况下,introduceBugs()被称为回调函数(callback function)或简称为回调(callback:):
function writeCode(callback) { // do something... callback(); // ... } function introduceBugs() { // ... make bugs } writeCode(introduceBugs);注意introduceBugs()作为一参数传递给writeCode()是没有使用括号的;
使用括号会立即执行函数,然而在这种情况下,我们希望的是只传递一个指向函数的引用,让writeCode()在适当的时候去执行;
var findNodes = function() { var i = 100000, // big, heavy loop nodes = [], // stores the result found; // the next node found while (i) { i -= 1; // complex logic here... nodes.push(found); } return nodes; };将这个函数保持通用性并让它返回一个DOM节点(node)的数组是个好主意,但没有对实际的元素做任何事情;
var hide = function(nodes) { var i = 0, max = nodes.length; for (; i < max; i += 1) { nodes[i].style.display = "none"; } }; // executing the functions hide(findNodes());这种实现是没有效率的,因为hide()不得不再遍历一次findNodes()返回的的数组;
// refactored findNodes() to accept a callback var findNodes = function(callback) { var i = 100000, nodes = [], found; // check if callback is callable if (typeof callback !== "function") { callback = false; } while (i) { i -= 1; // complex logic here... // now callback: if (callback) { callback(found); } nodes.push(found); } return nodes; };这样的实现是简单明确的,唯一增加的工作就是findNodes()检查了可选的回调函数是否有被提供,如果有,就执行它;
// a callback function var hide = function(node) { node.style.display = "none"; }; // find the nodes and hide them as you go findNodes(hide);
// passing an anonymous callback findNodes(function (node) { node.style.display = "block"; });
callback(parameters);虽然这样很简单并且在很多情况下都已经足够了;
var myapp = {}; myapp.color = "green"; myapp.paint = function(node) { node.style.color = this.color; };findNodes()函数做了类似下面的事:
var findNodes = function(callback) { // ... if (typeof callback === "function") { callback(found); } // ... };如果你调用了findNodes(myapp.paint),它并不能按照预期的那样工作,因为this.color将会是undefined;
findNodes(myapp.paint, myapp);紧跟着,我们需要去修改findNodes()去绑定(bind)传递进来的对象:
var findNodes = function(callback, callback_obj) { //... if (typeof callback === "function") { callback.call(callback_obj, found); } // ... };
findNodes(myapp.paint, myapp);会变成:
findNodes("paint", myapp);那么findNodes()可能会做一些事,就像下面几行:
var findNodes = function(callback, callback_obj) { if (typeof callback === "string") { callback = callback_obj[callback]; } //... if (typeof callback === "function") { callback.call(callback_obj, found); } // ... };
document.addEventListener("click", console.log, false);绝大部分客户端浏览器都是事件驱动的(event-driven);
var thePlotThickens = function () { console.log('500ms later...'); }; setTimeout(thePlotThickens, 500);再次注意一下,thePlotThickens是如何被作为一个参数传递的,没有使用括号;