前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实现观察者模式

实现观察者模式

作者头像
kifuan
发布2022-10-24 16:33:17
1640
发布2022-10-24 16:33:17
举报
文章被收录于专栏:随便写写-kifuan

源码

点击这里前往Github查看本文源码。

实现

我们要定义一个observer函数,它会把我们传入的对象复制一份再进行代理,并且返回的代理对象上还有一个observe方法,用来添加一个观察者:

代码语言:javascript
复制
function observable(obj) {
    const observers = {}
    
    // 使用Object.assign避免修改原对象
    const target = Object.assign({
        observe(key, fn) {
            observers[key] = fn
            // For method chaining
            return this
        }
    }, obj)

    const set = (target, key, value) => {
        const oldVal = Reflect.get(target, key)

        // 如果存在则调用当前属性对应的观察者回调函数,
        // 并且把它的旧值和新值传给回调函数
        observers[key]?.call(undefined, oldVal, value)
        
        return Reflect.set(target, key, value)
    }

    return new Proxy(target, { set })
}

其中我们使用了Object.assign来避免修改原对象,但是如果非要那么做也没什么大问题,只是容易出bug。

使用

注意我们传给它的回调是接受两个参数,第一个表示旧值,第二个表示新值:

代码语言:javascript
复制
const ob = observable({
    x: 0,
    y: 1,
}).observe('x', (oldVal, newVal) => {
    console.log(`x: ${oldVal} -> ${newVal}`)
}).observe('y', (oldVal, newVal) => {
    console.log(`y: ${oldVal} -> ${newVal}`)
})

ob.x = 10
// x: 0 -> 10

ob.y = 20
// y: 1 -> 20

读者可以打开控制台试一试效果。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码
  • 实现
  • 使用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档