观察者模式-js实现

/**
 * 
 * 观察者模式(发布-订阅者模式)
 * 
 * 实现方法v1
 */

var Observer = (function () {
    var _message = {} //防止队列暴漏而被篡改故将消息容器作为静态私有变量保存
    return {
        regist: function (type, fn) {
            // console.log("type",type);
            if (typeof _message[type] === 'undefined') {
                _message[type] = [fn]
            } else {
                _message[type].push(fn)
            }
        },
        fire: function (type, args) {
            if (!_message[type]) {
                return
            }
            var event = {
                type: type,
                args: args || {}
            }
            var len = _message[type].length
            for (let i = 0; i < len; i++) {
                _message[type][i].call(this, event)
            }
        },
        remove: function (type, fn) {
            if (_message[type] instanceof Array) {
                for (let i = _message[type].length - 1; i >= 0; i--) {
                    //如果存在改动作就在消息队列中移除相应的动作
                    _message[type][i] === fn && _message[type].splice(i, 1)
                }
            }
        }
    }
})()
// console.log(Observer);
//用学生老师来充当订阅者
var Student = function (result) {
    var that = this
    //学生回答结果
    that.result = result
    //模拟学生回答问题的动作
    that.say = function () {
        console.log(that.result);
    }
}
// console.log(Student);
Student.prototype.answer = function (question) {
    Observer.regist(question, this.say)
}
Student.prototype.sleep = function (question) {
    console.log(this.result + ' ' + question + ' 已被注销');
    Observer.remove(question, this.say)
}

//用老师来充当观察者(发布者)

var Teacher = function () {}
Teacher.prototype.ask = function(question)  {
    console.log('问题是:', question);
    Observer.fire(question)
}

var stu1 = new Student('学生1回答问题'),
    stu2 = new Student('学生2回答问题'),
    stu3 = new Student('学生3回答问题')
stu1.answer('什么是设计模式')
stu1.answer('简述观察者模式')
stu2.answer('什么是设计模式')
stu3.answer('什么是设计模式')
stu3.answer('简述观察者模式')
stu3.sleep('简述观察者模式')

var teac = new Teacher()
teac.ask('什么是设计模式')
teac.ask('简述观察者模式')

2.用proxy和reflect实现一个观察者模式

/**
 * 基于es6 proxy,reflect实现
 * v2
 */

class Student {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
}
let stu = new Student("zhangsan", "20")
//proxy
let handler = {
    set(target, key, value, receiver) {
        if (key === 'name') {
            console.log(`name 从 ${target[key]} 转变成 ${value}`);
        }
        // Reflect.set方法设置target对象的name属性等于value
        Reflect.set(target, key, value, receiver)
    }
}
let stuProxy = new Proxy(stu, handler)
stuProxy.name  = "lizhen"

console.log(stu);
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容