若是有个模块 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
另外能够加入「前端下午茶交流群」微信群,长按识别下面二维码便可加我好友,备注加群,我拉你入群~