JavaScript中的设计模式

javascript重要的设计模式有三种
一.单例模式
二.组合模式
三.观察者模式

单例模式
单例模式:不管实例化多少次对象都只占用一个对象的内存空间,为了不产生全局变量污染,需要通过闭包的形式调用相关的函数操作。
核心代码

let GQ = (//一个命名空间
        function () {
            function CreateObj(name, age) { //一个构造函数
                this.name = name;
                this.age = age;
            }
            CreateObj.prototype.fn1 = function () {
                console.log(this.name, this.age);
            }
            let res = null;
            return function (name, age) {//闭包的固定格式返回一个函数
                if (!res) {
                    res = new CreateObj();//实例化唯一的一个对象
                }
                CreateObj.call(res, name, age)//利用call传参数
                return res;
            }
        }
    )();
    let gq1 = GQ('gq', 20);
    gq1.fn1();
    let gq2 = GQ('sy', 20);
    gq2.fn1();
    console.log(gq1 == gq2);//证明只有一个对象的内存空间

组合模式
通常用于对象属于树状结构的编程,把底层的对象的函数放到上层的对象中去,通过上层的对象统一进行操作,用数组将底层的对象包含进去,再通过循环遍历,逐一执行函数。

 function Composite(name) {
        this.name = name;
        this.type = 'Composite'
        this.children = [];
    }
    Composite.prototype = {
        constructor: Composite,
        addChild: function (child) {
            this.children.push(child);
            return this
        },
        getChild: function (name) {
            let elemnets = [];
            let pushLeaf = function (item) {
                if (item.type === 'Composite') {
                    item.children.forEach((item) => {
                        arguments.callee(item)
                    })
                } else if (item.type === 'Leaf') {
                    elemnets.push(item);
                }
            }
            if (name && this.name !== name) {
                this.children.forEach(function (item) {
                    if (item.name === name && item.type === 'Composite') {
                        pushLeaf(item)
                    }
                    if (item.name !== name && item.type === 'Composite') {
                        item.children.forEach((item) => {
                            console.log(item)
                            arguments.callee(item)
                        })
                    }
                    if (item.name == name && item.type === 'Leaf') {
                        elemnets.push(item);
                    }
                })
            } else {
                this.children.forEach((item) => {
                    pushLeaf(item)
                })
            }
            return elemnets;
        },
        hardWorking: function (name) {
            let leafObject = this.getChild(name);
            console.log(leafObject)
            for (let i = 0; i < leafObject.length; i++) {
                leafObject[i].hardWorking();
            }
        },
        sleeping: function (name) {
        }
    }
    function Leaf(name) {
        this.name = name;
        this.type = 'Leaf'
    }
    Leaf.prototype = {
        constructor: Leaf,
        addChild: function (child) {
            throw new Error('不能用')
        },
        getChild: function (name) {
            if (this.name == name) {
                return this
            }
            return null
        },
        hardWorking: function () {
            console.log(this.name + '努力工作')
        },
        sleeping: function () {
            console.log(this.name + '快去睡觉')
        }
    }
    var p1 = new Leaf('张1');
    var p2 = new Leaf('张2');
    var p3 = new Leaf('张3');
    var p4 = new Leaf('张4');
    var p5 = new Leaf('张5');
    var p6 = new Leaf('张6');
    var p7 = new Leaf('张7');
    var p8 = new Leaf('张8');
    var p9 = new Leaf('张9');
    var p10 = new Leaf('张10');
    var p11 = new Leaf('张11');
    var p12 = new Leaf('张12');
    var dept1 = new Composite('北京开发部门');
    dept1.addChild(p1).addChild(p2).addChild(p3);
    var dept2 = new Composite('北京销售部门');
    dept2.addChild(p4).addChild(p5).addChild(p6);
    var dept3 = new Composite('长沙开发部门');
    dept3.addChild(p7).addChild(p8).addChild(p9);
    var dept4 = new Composite('长沙销售部门');
    dept4.addChild(p10).addChild(p11).addChild(p12);
    var org1 = new Composite('北京分公司');
    org1.addChild(dept1).addChild(dept2);
    var org2 = new Composite('长沙分公司');
    org2.addChild(dept3).addChild(dept4);
    var org = new Composite('总部');
    org.addChild(org1).addChild(org2);
    org.hardWorking('张2');

观察者模式
通常用于数据的双向绑定

class Observer {
        constructor(){
            this.obj = {}
        }
        on(type,fn){//向消息盒子type里添加fn事件
            if(!this.obj[type]){
                this.obj[type] = [fn]
                return this
            }else{
                this.obj[type].push(fn)
                return this
            }
        }
        emit(type,...val){//执行type盒子里的...val函数
            let arr = [...val]

            if(!this.obj[type]){
                return
            }else{
                for(let i=0;i<this.obj[type].length;i++){
                    for(let j=0;j<arr.length;j++){
                        if(arr[j] === this.obj[type][i]){
                            arr[i]()
                        }
                    }
                }
            }
        }
        off(type,fn){//删除消息盒子里的fn函数
            if(!this.obj[type]){
                return
            }else{
                for(let i=0;i<this.obj[type].length;i++){
                    if(this.obj[type][i] === fn){
                        this.obj[type].splice(i,1)
                        i--
                    }
                }
            }
        }
    }
    let obs1 =new Observer();
    obs1.on('call',you).on('call',me).on('call',he)
    obs1.on('play',lan).on('play',zu).on('play',ping)
    obs1.off('call',he)

    obs1.emit('call',you,me,he)
    obs1.emit('play',lan,zu,ping)
    function you(){
        console.log('you')
    }
    function me(){
        console.log('me')
    }
    function he(){
        console.log('he')
    }
    function lan(){
        console.log('lan')
    }
    function zu(){
        console.log('zu')
    }
    function ping(){
        console.log('ping')
    }
发布了5 篇原创文章 · 获赞 26 · 访问量 240

猜你喜欢

转载自blog.csdn.net/qq_37826599/article/details/104561782