JavaScript 设想形式

1. 单例形式

  • 定义:一个特定类 唯一一个实例

  • 运用场景: 一个遮罩层

  • 完成体式格局

    1. 每一个对象都是一个单体,由于他们的援用位置不一样;

    2. 运用new操纵符

      • 将初次天生的对象存储在全局变量中。瑕玷:全局变量易被掩盖。能够运用闭包来存储这个变量,拜见 一个遮罩层

      • 在组织函数的属性中存储该实例。瑕玷:组织函数的属性也轻易被修正。

        function Universe() {
            if (typeof Universe.instance === "object") {
                return Universe.instance
            }

            this.start_time = 0;
            this.bang = "Big";

            Universe.instance = this;
        }

        var uni1 = new Universe();
        var uni2 = new Universe();

        console.log(uni1 === uni2); // true    
    - 重写组织函数,运用闭包来贮存这个实例。瑕玷:
//瑕玷: 这类体式格局会丢掉初始实例与重写组织函数之间的关联,因而背面再向重写的组织函数原型中增加属性时,并不会增加到初始实例中去。
        function Universe() {
            var instance = this;
            this.start_time = 0;
            this.bang = "Big";

            Universe = function Universe() {
                return instance;
            }
        }

        Universe.prototype.nothing = true;
        var uni1 = new Universe();

        Universe.prototype.everything = true;
        var uni2 = new Universe();

        console.log(uni1 === uni2); //true
        console.log(uni1.nothing); //true
        console.log(uni2.nothing); //true
        console.log(uni1.everything); //undefined
        console.log(uni2.everything); //undefined    
        console.log(uni1.constructor === Universe); //false

因而,我们须要先重写组织函数、保存原型属性、天生实例,返回实例。

        function Universe() {
            var instance;
            
            Universe = function () {
                return instance;
            }

            Universe.prototype = this;

            instance = new Universe();
            instance.constructor = Universe;

            this.start_time = 0;
            this.bang = "big";

            return instance;
        }

        Universe.prototype.nothing = true;
        var uni1 = new Universe();

        Universe.prototype.everything = true;
        var uni2 = new Universe();

        console.log(uni1 === uni2); //true
        console.log(uni1.nothing); //true
        console.log(uni2.nothing); //true
        console.log(uni1.everything); //true
        console.log(uni2.everything); //true
        console.log(uni1.constructor === Universe); //true
- 另有一种就是运用立即函数
        var Universe;
        (function () {
            var instance;
            Universe =     function () {
                if (instance) {
                    return instance;
                }

                instance = this;
                this.start_time = 0;
                this.bang = "big";
            }
        })();

        Universe.prototype.nothing = true;
        var uni1 = new Universe();

        Universe.prototype.everything = true;
        var uni2 = new Universe();

        console.log(uni1 === uni2); //true
        console.log(uni1.nothing); //true
        console.log(uni2.nothing); //true
        console.log(uni1.everything); //true
        console.log(uni2.everything); //true
        console.log(uni1.constructor === Universe); //true    

2. 工场形式

  • 定义: 供应建立类似对象的可重用要领。在不确定的情况下,提早供应一种建立某类的要领。总-分形式。

  • 运用场景:一个CarMaker的组织函数,供应建立差别范例汽车的factory要领。

  • 完成体式格局。长处:庇护全局定名空间免受污染,能很快地找到响应的组织函数。

        function CarMaker() {}
        
        CarMaker.prototype.getPrice =     function () {
            console.log("Price:", this.price);
        }

        CarMaker.factory = function (type) {
            var newcar;
            //假如组织函数不存在,报错
            if (typeof CarMaker[type] !== "function") {
                throw {
                    name: "Error",
                    message: type + " dosen't exist"
                }
            }

            //原型继续父类,且只继续一次
            if (typeof CarMaker[type].prototype.getPrice !== "function") {
                CarMaker[type].prototype = new CarMaker();
            }

            newcar = new CarMaker[type]();
            return newcar;
        }

        CarMaker.SUV = function () {
            this.price = 100;
        }

        CarMaker.Compat = function () {
            this.price = 50;
        }

        var a = CarMaker.factory("SUV");
        var b = CarMaker.factory("Compat");

        a.getPrice(); //Price: 100
        b.getPrice(); //Price: 100

3. 迭代器形式

  • 定义:按递次接见一个聚合对象中各个元素。一般包括next(猎取下一个元素), hasNext(是不是到末端),rewind(重置初始位置), current(当前元素)鸠合要领。

  • 运用场景:须要依据递次,以差别的距离猎取鸠合中的元素。

  • 完成要领:

function iterator (data = [], gap = 1) {
         var index = 0, //纪录当前位置
                 length = data.length; //数据总长度
         return {
             next() {
                 var element;
                 if (!this.hasNext()) {
                     return null;
                 }
                 element = data[index];
                 index += gap;
                 return element;
             },
             hasNext() {
                 return index < length;
             },
             rewind() {
                 index = 0;
             },
             current() {
                 return data[index];
             }
         }
     }

     var arrIterator = iterator([1, 2, 3, 4, 5]);

     while(arrIterator.hasNext()) {
         console.log(arrIterator.next());
     }

     arrIterator.rewind();
     console.log(arrIterator.current());

4. 装潢者形式

  • 定义: 在运行时动态增加附加功能到对象中。

  • 运用场景:购置某种东西时,跟着增加差别的装备,价钱也不一样。末了须要依据增加的装备盘算总价。

  • 完成要领:要注意的是,各装潢器须要供应原型要领的接口。 另一种完成体式格局

        function Sale(price = 100) {
            this.price = price;
            this.decorators_list = [];
        }

        //装潢器
        Sale.decorators = {};
        Sale.decorators.pack = {
            getPrice(price) {
                return price + 20;
            }
        }
        Sale.decorators.mail = {
            getPrice(price) {
                return price + 10;
            }
        }

        Sale.prototype.decorate = function (decorator) {
            this.decorators_list.push(decorator);
        }

        Sale.prototype.getPrice = function () {
            let price = this.price;
            //挪用各装潢器的接口
            for (let i = 0, len = this.decorators_list.length; i < len; i++) {
                name = this.decorators_list[i];
                price = Sale.decorators[name].getPrice(price);
            }
            return price;
        }

        var sale = new Sale();
        sale.decorate('pack');
        sale.decorate('mail');
        console.log(sale.getPrice()); //130

5. 战略者形式

  • 定义:在运行时能够挑选算法。

  • 运用场景:表单考证。

  • 完成体式格局:一个含有config(设置考证划定规矩), types(考证范例), validate(考证要领), message(效果音讯数组), hasErrors(末了构造)几个属性的validator对象。

6. 表面形式

  • 定义:供应一个高等接口,挪用常常须要同时运用的几个基本要领。

  • 运用场景:将stopPropagationpeventDefault包装在stop这个高等接口中。

饭堂的炒菜师傅不会由于你预定了一份烧鸭和一份白菜就把这两样菜炒在一个锅里。他更情愿给你供应一个烧鸭饭套餐。同样在顺序设计中,我们须要保证函数或许对象尽量的处在一个合理粒度,毕竟不是每一个人喜欢吃烧鸭的同时又恰好喜欢吃白菜。

表面形式另有一个优点是能够对用户隐蔽真正的完成细节,用户只体贴最高层的接口。比方在烧鸭饭套餐的故事中,你并不体贴师傅是先做烧鸭照样先炒白菜,你也不体贴那只鸭子是在那里生长的。

7. 代办形式

  • 定义:介于对象和对象的客户端之间,对对象本体起庇护作用,使本体对象做尽量少的事情。目标是处置惩罚机能题目。

  • 运用场景:

    • 初始化本体对象斲丧非常大,然则在初始化该对象的以后并未运用。此时可运用代办形式,吸收初始化要求,返回ok,等真正用到本体对象时再初始化。

    • 提议Http要求会斲丧机能,最好的要领就是运用代办兼并Http要求,比方将50ms内的提议的要求兼并为一个要求。

    • 为了削减机能斲丧,还可给代办设置一个缓存,缓存效果。

    • fragment应当就算一个代办形式吧,缓存了对DOM的操纵。

  • 完成要领:对象客户端挪用代办供应的要领,代办对客户端的要求举行处置惩罚后挪用对象本体要领。

8. 中介者形式

  • 定义:一个顺序中有许多对象,这些对象之间会互相通讯。然则假如修正个中一个对象,则必然会牵涉到其他和他通讯的对象,构成紧耦合。中介者形式就是提出一个中心对象来完成对象间的松耦合通讯。通讯的对象不必晓得对方是谁,只需有更改就关照给这个中介者,中介者晓得一切的对象而且担任联络响应的对象做出处置惩罚。

  • 运用场景:MVC中的Controller

  • 完成要领:http://www.jspatterns.com/boo…

9. 观察者形式

  • 定义:该形式的目标也是为了构成松耦合。对象之间不直接挪用相互的要领,而是采用定阅的形式,定阅者定阅宣布者的事宜,并向宣布者供应一个事宜发作时挪用的要领。中介者形式中的mediator须要晓得一切其他对象,而该形式并不须要晓得,只需定阅事宜即可。

  • 运用场景:DOM中的事宜。

  • 完成要领:
    宣布者须要:定阅者的列表{type: []},定阅要领, 作废定阅,宣布音讯几种要领。http://www.jspatterns.com/boo…

    原文作者:Yawenina
    原文地址: https://segmentfault.com/a/1190000008661444
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞