js设计模式

260 阅读2分钟

1 单例模式Singleton

核心代码
      var Person = (function () {
      function Person() {}
      var instance = null
      return function () {
        return !instance ? instance = new Person() : instance
      }
    })()
	

    p1=new Person()
    p2=new Person()
    console.log(p1==p2)//true
应用场景
  • 网站的弹出层alert()或者右下角的广告页面
  • 一个网站不可能只弹出一次这个界面,不能每次弹出就创建一个
  • 每次弹出的都是之前创造好的,只是内容发生变化

2 组合模式

核心代码
    class Play {
      constructor () {}

      init () {
        console.log('开始玩游戏')
        this.a()
        this.b()
        this.c()
      }

      a () {}

      b () {}

      c () {}
    }

    class Eat {
      constructor () {}

      init () {
        console.log('去吃饭')
      }
    }
    class Sleep {
      constructor () {}

      init () {
        console.log('去睡觉')
      }
    }


    class Compose {
      constructor () {
        this.composeArr = []
      }

      add (instance) {
        this.composeArr.push(instance)
      }

      init () {
        console.log('总开关启动了')
        this.composeArr.forEach(item => item.init())
      }
    }

    var c = new Compose()
    c.add(new Play())
    c.add(new Eat())
    c.add(new Sleep())
    
    c.init()
    console.log(c)
应用场景
  • 一个页面上有许多轮播图,当我切换其他标签页面时,这个页面上的轮播图还在运行,定时器没有停止
  • 设置离开这个页面时,定时器停止,轮播图停止运动
  • 这时就可以利用组合模式,设置一个总开关,控制所有轮播图的停止与运动。

3 发布订阅模式

核心代码
        function handlerA(e) { console.log('我是事件处理函数 handlerA', e) }
        function handlerB(e) { console.log('我是事件处理函数 handlerB', e) }
        function handlerC(e) { console.log('我是事件处理函数 handlerC', e) }
        function handlerD(e) { console.log('我是事件处理函数 handlerD', e) }
        function handlerE(e) { console.log('我是事件处理函数 handlerE', e) }


        class Observer {
            constructor() {
                //  准备好的消息盒子
                this.message = {}
            }

            // 订阅的方法
            on(type, fn) {
                // type  要订阅 事件类型   fn  事件处理函数
                // 如果  message 盒子中  没有  type  就添加
                // 如果  message 盒子中  有  type  就添加 事件函数
                if (!this.message[type]) {
                    this.message[type] = []
                }
                this.message[type].push(fn)
            }

            // 取消订阅的方法
            off(type, fn) {
                // 删除消息盒子里面的某一个成员
                // type  要取消的 事件类型   fn  事件处理函数
                // 如果  message 盒子中  没有  type 不操作
                // 如果  message 盒子中  有  type  删除
                if (!this.message[type]) return
                this.message[type] = this.message[type].filter(item => item != fn)

            }

            // 发布的方法
            emit(type, ...arg) {
                // 没有 订阅过 type  不操作
                //      订阅过 type  执行

                 if (!this.message[type]) return
                // 自己组装一个事件对象
                let event = {
                    type: type,
                    data: arg
                }

                this.message[type].forEach(element => element(event))

            }

        }


        let ob = new Observer()

        console.log('订阅   发布')
        ob.on('click', handlerA)
        ob.on('click', handlerB)
        ob.on('click', handlerC)
        ob.on('abc', handlerD)
        ob.on('abc', handlerE)

        ob.emit('click', 100, true, { name: '小明' }, [1, 2, 3, 4])
        ob.emit('abc', 200, true, { name: '小红' }, [1, 2, 3, 4])

        console.log('')

        console.log('取消订阅  handlerA handlerD 然后  发布')
        ob.off('click', handlerA)
        ob.off('abc', handlerD)

        ob.emit('click', false,{name:'小明'})
        ob.emit('abc',false,{name:'小红'})
应用场景

vue 传参 传递事件

4 观察者模式

核心代码
class student {
            constructor(name) {
                this.name = name
                this.state='学习'
                this.observers=[]
            }

            setState(state){
                this.state=state
                this.noticy()
            }

            getState(){
                return this.state
            }

            attach(observer){
                this.observers.push(observer)
            } 

            noticy(){
                     this.observers.forEach(item=>item.jiaojiazhang(this.name,this.state))
            }

        }

        class teacher{
            constructor(name){
                this.name=name
            }

            jiaojiazhang(name,state){
                console.log(`我是  ${this.name}  因为  ${name}${state},我要叫家长 `)
            }
        }

        let s=new student('小明')
        console.log(s)//student {name: "小明", state: "学习", observers: Array(0)}


        // 添加  观察者
        let ob1=new teacher('班主任')
        let ob2=new teacher('教导主任')

        console.log(ob1)
        console.log(ob2)

        s.attach(ob1)
        s.attach(ob2)


        //先获取最开始的状态
        console.log(s.getState())
		// 状态改变    改变后观察者 直接执行方法
        s.setState('上课吃辣条')
        //状态改变后的状态
        console.log(s.getState())
应用场景

状态改变则做一件事情