JS 回调模式

SHERlocked93

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() 中实现修改逻辑,由于检索和修改逻辑耦合,那么它将不再是一个通用函数。对这种问题的解决方法是采用回调模式

可以将节点隐藏逻辑以回调函数的方式传递给 findNodes() 并委托执行:

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 将指向的是全局对象,从而发生意外。

解决这个问题的方法是传递回调函数,并且还传递该回调函数所属的对象:

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 观察者模式

网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~

参考:<JavaScript 模式> P65

PS:欢迎大家关注我的公众号【前端下午茶】,一起加油吧~

另外可以加入「前端下午茶交流群」微信群,长按识别下面二维码即可加我好友,备注加群,我拉你入群~

阅读 1.3k

前端下午茶公众号
你不能把这个世界,让给你鄙视的人

来自南京的前端打字员,掘金优秀作者,慕课畅销专栏 <JavaScript 设计模式精讲> 作者,原创同步更新于 Github 个人博客 (求 star🤪 )

5.6k 声望
391 粉丝
0 条评论

来自南京的前端打字员,掘金优秀作者,慕课畅销专栏 <JavaScript 设计模式精讲> 作者,原创同步更新于 Github 个人博客 (求 star🤪 )

5.6k 声望
391 粉丝
宣传栏