javascript设计模式 观察者模式

javascript设计模式 观察者模式
2016-06-07

别人端午节放假 我却还上班

观察者模式; 我通过看书籍觉得似乎是有两种场景做法;
上代码

(如果有意见请提出来,我写博客也是为了学习、分享,先学习 后分享。我也是新人,代码肯定有问题,思路肯定也有局限性,不怕批评,就怕你不指出来 谢谢大家!)

//首先整个观察者模式 是通过被观察者订阅观察者;当有关状态被改变的时候,观察者通过广播通知被观察者,
//一种是先写好被通知之后干嘛
//一种是先通知,然后自己来定义  先通知你了 然后定义你要去干嘛
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="d"></div>

javascript代码

    //页面有四个元素, 当钱发生变化的时候, 我需要给他们加上去
        function observer(){
            this.observerList = [];
        }
        //订阅
        observer.prototype.add = function(obj) {
            //先来判断这里是否已经被注册了
            var is = this.observerList.some(function(e){
                return e === obj;
            })

            if(!is){
                this.observerList.push(obj);
            }
        };

        observer.prototype.$ = function(ele) {
            //一般情况下,如果我获取的DOM对象不需要用到jquery方法,我很少用$(ele),因为这样没必要,影响性能
            //就算你之后要重新用到jquery方法 也可以把这个原声的dom对象转为jquery对象
            return document.getElementById(ele);
        };

        //通知
        observer.prototype.Notify = function(price) {
            //这个地方我先定义好我要做的事情,给订阅的元素加钱
            this.observerList.forEach(function(e){
                e.innerText = (Number(e.innerText) + Number(price)).toFixed(2);`

            })
        };

然后就是订阅

       //首先创建一个实例
        var ob = new observer();
        //订阅
        ob.add(ob.$("a"))
        ob.add(ob.$("b"))
        ob.add(ob.$("c"))
        ob.add(ob.$("d"))
        //发布钱
        ob.Notify("500.02");

这是预先说好,我这个观察者模式给页面的金钱发生改变时,用来广播的

还有一种就是订阅者订阅我这个东西,当这个东西被发布了,我就去通知他,“你订阅的东西发布啦”,然后订阅者就是看发布的内容,根据内容去做处理逻辑;

代码

        function observer(){
            //注意这里是对象
            this.observerList = {};
        }

        //订阅
        observer.prototype.listen = function(key,fn) {
            // body...
            var stack,clonekey;
            //这里判断它是不是创建过订阅键值, 有的话直接把我们绑定的回调放进去, 没有就新建一个数组放进去
            stack = (clonekey = this.observerList[key]) != null ? clonekey : this.observerList[key] = [];
            stack.push(fn);
        };

        //发布
        observer.prototype.Notify = function() {
             //这里不传参数, 因为我们不知道它发布的时候要用到多少东西,所以我们直接用arguments获取
             var stack,clonekey,key,self = this,fn;
             key = Array.prototype.shift.call(arguments);//获取订阅的名称;
             //取到订阅键值的值
             stack = (clonekey = this.observerList[key]) != null ? clonekey : this.observerList[key] = [];
             //发布
             for(var _i = 0,_max = stack.length; _i < _max; _i++){
                fn = stack[_i];
                fn.apply(self,arguments)
             }

        };


        //订阅
        var ob = new observer();
        ob.listen("watch",function(data,b,c){
            //这里订阅了节目
            console.log(data + " " + b + " " + c)
            alert("今天听说有"+data.name);
        })

        //电视台发布
        ob.Notify("watch",{name : "铁甲小宝"})

大概是这样了,

apply 跟 call还是有点迷糊
apply 是把参数整合成一个数组
call是把参数分开来传
看起来是没多大的区别,、
可是这里的fn.apply(self,arguments)为什么我使用call传过去是一个数组,而apply却是一个对象
简单分析一下:
apply是传的一个数组,当了下一个流程的时候我们假设javascript解释器会把参数数组自动拆分成一个一个的参数,所以这里明明传的是数组,外面的数组壳没了却成为了一个对象
call是传的一个一个的值,所javascript解释器不会做多余的修饰操作,传的是什么就是什么
谢谢大家的阅读,希望能给我提意见 谢谢大家

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值