JavaScript 观察者模式详解:从原理到代码实现

作者:闭包旅人

时间:2026-10-24

浏览:453

本文深入解析 JavaScript 中的观察者模式,阐述其一对多依赖关系的核心原理。通过双11购物场景模拟发布者、被观察者与观察者的交互,并展示基础代码实现。随后对代码进行重构优化,提升可扩展性,帮助开发者掌握该设计模式的实际应用。

文章目录

什么是观察者模式?

  • 观察者模式是一种常见的设计模式。
  • 该模式定义了对象之间的一种一对多依赖关系。当其中一个对象的状态发生改变时,所有依赖于它的对象都会收到通知,并自动执行更新操作。
  • 简单来说,观察者模式包含两个核心模型:观察者(Observer)和被观察者(Observed)。当被观察者的状态发生变动时,它会主动通知所有注册的观察者。

场景模拟

  • 假设即将到来的双11购物节,所有打算购买特定商品的用户即为观察者(Observer)。
  • 用户想要购买的具体商品即为被观察者(Observed)。
  • 为了更形象地说明,我们引入一个商家角色来调整商品价格,商家在此处充当发布者(Publish)的角色。
  • 在双11当天,商家(发布者)修改商品(被观察者)的价格后,所有关注或订阅该商品的用户(观察者)都会收到通知信息。

什么是观察者模式?

代码实现


//观察者设计模式
//发布者 -->商家
var shopObj = {};
//商品列表 [key:[]], key为商品名
shopObj.list = [];
//订阅方法
shopObj.listen = function ( key, fn) {// key是商品型号, fn这个函数就是订阅的行为
    if (!this.list[key]) {
        this.list[key] = [];
    }
    this.list[key].push(fn);//往商品名为key的商品列表中添加订阅
}
//发布消息方法
shopObj.publish = function (key) {
    //var key = arguments[0];//如果不传参数key,这样也可以
    var fns = this.list[key];
    // for (var i = 0; i < fns.length; i++) {
        for(var i = 0 ,fn; fn = fns[i++];){
        //执行订阅的函数fn  arguemnts储存的所有实参
        // var fn = fns[i++];
        fn.apply(this, arguments)
    }
}
//A用户添加订阅
shopObj.listen("华为", function (brand, model) {
    console.log( "A用户收到:" + brand + model + "手机降价了");
})
//B用户添加订阅
shopObj.listen("华为", function (brand, model) {
    console.log("B用户收到:" + brand + model + "手机降价了");
})
//c用户添加订阅
shopObj.listen("小米", function (brand, model) {
    console.log("C用户收到:" + brand + model + "手机降价了");
})
//双11 商家发布消息华为降价的信息
shopObj.publish("华为", "p30");
shopObj.publish("小米", "Mix4");

什么是观察者模式?

重构代码


//观察者设计模式
var Eevent = {
    //商品列表 [key:[]], key为商品名
    list: [],
    //订阅方法
    listen: function (key, fn) {// key是商品型号, fn这个函数就是订阅的行为
        if (!this.list[key]) {
            this.list[key] = [];
        }
        this.list[key].push(fn);
    },
    //发布消息方法
    publish: function (key) {
        //var key = arguments[0];//如果不传参数key,这样也可以
        var fns = this.list[key];
        // for (var i = 0; i < fns.length; i++) {
        for (var i = 0, fn; fn = fns[i++];) {
            //执行订阅的函数fn  arguemnts储存的所有实参
            // var fn = fns[i++];
            fn.apply(this, arguments)
        }
    }
}
//观察者对象初始化
var initEvent = function (obj) {
    for (var i in Eevent) {
        obj[i] = Eevent[i];
    }
}
//发布者 -->商家
var shopObj = {};
initEvent(shopObj);
//A用户添加订阅
shopObj.listen("华为", function (brand, model) {
    console.log("A用户收到:" + brand + model + "手机降价了");
})
//B用户添加订阅
shopObj.listen("华为", function (brand, model) {
    console.log("B用户收到:" + brand + model + "手机降价了");
})
//c用户添加订阅
shopObj.listen("小米", function (brand, model) {
    console.log("C用户收到:" + brand + model + "手机降价了");
})
//双11 商家发布消息华为降价的信息
shopObj.publish("华为", "p30");
shopObj.publish("小米", "Mix4");

什么是观察者模式?

总结

本文到此结束,希望能为读者带来帮助,同时也欢迎大家关注本站以获取更多技术内容。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章