美文网首页
前端设计模式

前端设计模式

作者: 辉夜乀 | 来源:发表于2017-05-25 15:38 被阅读63次
    • 模块模式
    • 工厂模式
    • 构造函数模式
    • 混合模式
    • 单例模式
    • 发布订阅模式

    模块模式

    用于模块封装,用立即执行的函数嵌套一下,定义了一些私有的变量和方法,只 return 出一些供外部使用的接口,外部只能访问这些接口,无法访问私有的变量和方法

    <script type="text/javascript">
        var Person = (function(){
            var name = "cg";
            return {
                changeName: function(newName){
                    name = newName;
                },
                sayName: function(){
                    console.log(name);
                }
            }
        })()
    
        Person.sayName()
        Person.changeName("hello")
        Person.sayName()
    
        /*模块模式:用于模块封装,用立即执行的函数嵌套一下,定义了
        一些私有的变量和方法,只 return 出一些供外部使用的接口,外
        部只能访问这些接口,无法访问私有的变量和方法.
        */
    </script>
    

    工厂模式

    工厂模式相当于构造函数模式的简化版,能创建对象,但是没有构造函数,无法用 instanceof 的方法判断是否为实例

    <script type="text/javascript">
        function createPerson(opts){
            var person = {
                name: opts.name || "cg"
            };
            person.sayName = function(){
                console.log(this.name);
            };
            return person;
        }
    
        var p1 = createPerson({name: "cg"})
        p1.sayName() //cg
    
        var p2 = createPerson({name: "ly"})
        p2.sayName() //ly
    
        /*工厂模式相当于构造函数模式的简化版,能创建对象,
        但是没有构造函数,无法用 instanceof 的方法判断是否为实例
        */
    </script>
    
    

    构造函数模式

    构造函数模式,把私有的属性绑定到this上,把公用的方法绑定到构造函数的原型对象上,使用 new 关键词创建实例

    <script type="text/javascript">
        function Person(name, age){
            this.name = name;
            this.age = age;
        }
    
        Person.prototype.sayName = function(){
            return this.name;
        }
    
        var student = new Person("cg", "25")
        console.dir(student);
    
        /*构造函数模式,把私有的属性绑定到this上,
        把公用的方法绑定到构造函数的原型对象上,
        使用 new 关键词创建实例
        */
    </script>
    

    混合模式

    混合模式:子类继承父类的属性和方法,子类再绑定自己的属性和方法,是构造函数模式的扩展。

    <script type="text/javascript">
        var Person = function(name, age){
            this.name = name;
            this.age = age;
        }
    
        Person.prototype.sayName = function(){
            console.log(this.name);
        }
    
        var Student = function(name, age, score){
            Person.apply(this, arguments); //Student函数继承Person函数的方法
            this.score = score;
        }
    
        Student.prototype = Object.create(Person.prototype) //ES5方法,原型链继承
    
        //以下三行代码等效 Object.create ,兼容IE
        // function Fn(){}
        // Fn.prototype = Person.prototype
        // Student.prototype = new Fn()
    
        Student.prototype.constructor = Student //修正构造函数
    
        Student.prototype.sayScore = function(){
            console.log(this.score)
        }
    
        var student = new Student("cg", 25, 100)
    
        console.dir(student)
    
        /*混合模式:子类继承父类的属性和方法,
        子类再绑定自己的属性和方法
        是构造函数模式的扩展。
        */
    </script>
    

    单例模式

    单例模式的特点是,如果对象不存在,会初始化创建,存在后,无论调用几次,得到的永远是同一个对象

    <script type="text/javascript">
        var people = (function(){
            var instance;
            function init(){
                //define private methods and properties
                //do something
                return {
                    //define public methods and properties
                }
            }
            return {
                createPeople: function(){
                    if(!instance){
                        instance = init();
                    }
                    return instance;
    
                }
            }
        })()
    
        var obj1 = people.createPeople()
        var obj2 = people.createPeople()
    
        console.log(obj1 === obj2)  //true
    
        /*单例模式的特点是,如果对象不存在,会初始化创建,
        存在后,无论调用几次,得到的永远是同一个对象
        */
    </script>
    

    发布订阅模式

    发布订阅模式,可以自定义事件,绑定事件类型和处理方法,之后如果要对该事件绑定同样的方法,只要订阅该事件即可

    <script type="text/javascript">
        var EventCenter = (function(){
    
            var events = {}
    
            //发布事件,自定义一个事件以及
            function addEvent(evt, handler){
                events[evt] = events[evt] || [];
                events[evt].push({  //绑定多个方法
                    handler: handler
                })
            }
    
            //订阅事件,如果该事件被添加发布过,则执行相应的函数方法
            function fire(evt, args){
                if(!events[evt]){
                    return
                }
                for(var i=0; i<events[evt].length; i++){
                    events[evt][i].handler(args)  //执行绑定的每个方法
                }
            }
    
            //删除事件,用 delete 删除 events 对象中的属性
            function off(evt){
                delete events[evt]
            }
    
            return {
                addEvent: addEvent,
                fire: fire,
                off: off
            }
        })()
    
        EventCenter.addEvent("myEvent", function(data){
            console.log("myEvent received...");
        })
        //发布事件
    
        EventCenter.fire("myEvent")
        //订阅事件,如果该事件被添加发布过,则执行相应的函数方法
    
        EventCenter.off("myEvent")
        //删除事件 myEvent 事件
    
    </script>
    
    

    使用发布订阅模式写一个事件管理器,可以实现如下方式调用

    Event.on('change', function(val){
        console.log('change...  now val is ' + val);  
    });
    Event.fire('change', '饥人谷');
    Event.off('changer');
    
    <script type="text/javascript">
        var Event = (function() {
            var events = {};
    
            function on(evt, handler) {
                events[evt] = events[evt] || [];
                events[evt].push({
                    handler: handler
                })
            }
    
            function fire(evt, args) {
                if (!events[evt]) {
                    return
                }
                for (var i = 0; i < events[evt].length; i++) {
                    events[evt][i].handler(args)
                }
            }
    
            function off(evt) {
                delete events[evt];
            }
            return {
                on: on,
                fire: fire,
                off: off
            }
        })()
    
    
    
        Event.on('change', function(val) {
            console.log('change...  now val is ' + val);
        });
        //发布事件
    
        Event.fire('change', '饥人谷');
        //订阅事件,change...  now val is 饥人谷
    
        Event.off('change');
        //删除事件
    
        Event.fire('change', '饥人谷');
        //undefined 因为 change 事件被删除了,订阅不到
    
    </script>
    

    相关文章

      网友评论

          本文标题:前端设计模式

          本文链接:https://www.haomeiwen.com/subject/zshzxxtx.html