• JavaScript模式读书笔记 第7章 设计模式


    1,单例模式
        -1,最简单的单例:
         
    <script>
    //obj为单例
    var obj = {
    myProp: "My Value"
    };
    var obj1 = obj;
    var obj2 = obj;
    console.log(obj1 == obj2);//true
    console.log(obj1 === obj2);//true
      </script>
    -2,静态属性中的实例:
        
     <script>
    function Universe(){
    if(typeof Universe.instance === "object"){
    return Universe.instance;
    }
     
    this.start_time = 0;
    this.bang = "Big";
     
    Universe.instance = this;
    }
     
    var u1 = new Universe();
    var u2 = new Universe();
    console.log(u1 === u2);//true
      </script>
        缺点:Universe.instance是公开的属性,其他代码可能无意更改此属性.
    -3,闭包中的实例
        
      <script>
    function Universe(){
    //缓存私有变量
    var instance = this;
     
    this.start_time = 0;
    this.bang = "Big";
    //重写构造函数,返回私有变量
    Universe = function(){
    return instance;
    };
    }
    var u1 = new Universe();
    var u2 = new Universe();
    console.log(u1 === u2);//true
      </script>
    上述代码在第一次调用的时候返回this,在第二次、第三次调用的时候,将会重写构造函数,该重写构造函数通过闭包访问了私有的instance属性,并且只是简单返回该Instance。见如下代码:
        
     
      <script>
    function Universe(){
    //缓存私有变量
    var instance = this;
     
    this.start_time = 0;
    this.bang = "Big";
    //重写构造函数,返回私有变量
    Universe = function(){
    return instance;
    };
    }
    Universe.prototype.nothing = true;
    var u1 = new Universe();
    Universe.prototype.everything = true;
         var u2 = new Universe();
     
     
    console.log(u1.nothing);//true
    console.log(u2.nothing);//true
         console.log(u1.everything);//undefined
    console.log(u2.everything);//undefined
      </script>
    因为u1的constructor指向了原始的构造函数,而不是重新定义的构造函数。(这块还是没搞明白。。。。。。只是觉得好神奇)
     下面的例子,在构造函数重新定义了对应的constructor。
           
     function Universe(){
    //缓存私有变量
    var instance ;
     
    //重写构造函数,返回私有变量
    Universe = function  Universe(){
    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 u1 = new Universe();
    Universe.prototype.everything = true;
         var u2 = new Universe();
     
     
    console.log(u1.nothing);//true
    console.log(u2.nothing);//true
         console.log(u1.everything);//true
    console.log(u2.everything);//true
      </script>
    2,工厂模式
        设计工厂模式是为了创建对象,它通常在类或者类的静态方法中实现,具有下列目标:
            a. 当创建相似对象时执行重复操作。
            b.在编译时不知道具体类型的时候,为工厂客户提供一种创建对象的接口。
     
    <script>
    function CarMaker(){
    CarMaker.prototype.drive = function(){
    return "Vroom, I hava " + this.doors + " doors";
    };
     
    //静态工厂方法 
    CarMaker.factory = function(type){
    var constr = type, newCar;
     
    if(typeof CarMaker[constr] !== "function"){
    throw{
    name: "Error",
    message: constr + " doesn't exist";
    };
    }
    //工厂方法
    if(typeof CarMaker[constr].prototype.drive !== "function"){
    CarMaker[constr].prototype = new CarMaker();
    }
    newCar = new CarMaker[constr]();
    return newCar;
    };
     
    CarMaker.compact = function(){
    this.doors = 4;
    };
    CarMaker.convertible = function(){
    this.doors = 2;
    };
     
    CarMaker.SUN = function(){
    this.doors = 24;
    };
    }
      </script>
    内置工厂模式:
         
    <script>
    var o = new Object(),
    n = new Object(1),
    s = Object('1'),
    b = Object(true);
     
    console.log(o.constructor === Object);//true
    console.log(n.constructor === Number);//true
    console.log(s.constructor === String);//true
    console.log(b.constructor === Boolean);//true
      </script>
    3,迭代器模式
        遍历复杂数据结构,具体调用格式类似java集合类。
    <script>
    var element;
    while(element = agg.next){
    //业务处理
    console.log(element);
    }
      </script>
        
     <script>
    var agg = (function(){
    var index = 0, 
    data = [1, 2, 3, 4, 5],
    length = data.length;
    return {
    next: function(){
    var element;
    if(!this.hasNext()){
    return null;
    }
    element = data[index];
    index = index + 1;
    return element;
    },
    hasNext: function(){
    return index < length;
    },
    rewind: function(){
    index = 0;
    },
    current: function(){
    return data[index];
    }
    };
    }());
    agg.rewind();
    console.log(agg.current());//1
    while(agg.hasNext()){
    console.log(agg.next());// 1 2 3 4 5
    }
      </script>

    4,装饰者模式
        装饰者模式,可以在运行时动态添加附加内容到对象中。装饰者模式可以从仅具有基本功能的普通对象开始,然后从可用装饰资源池中选择需要用于增强普通对象的那些功能,并且安装顺序进行装饰,尤其是当装饰顺序很重要的时候。
        例如如下场景,根据固定的商品价格a,我们可以组合不同的税收,最后得出不同的最终价格。
        
      <script>
    var sale = new Sale(100);
    sale = sale.decorator("fedtax");//增加联邦税
    sale = sale.decorator("quebec");//增加省税
    sale = sale.decorator("money");//以美元形式展示
    sale.getPrice();//"$112.88"
     
    //使用不同的税收策略
    var sale = new Sale(100);
    sale = sale.decorator("fedtax");//增加联邦税
    sale = sale.decorator("cdn");//以cdn形式展示
    sale.getPrice();//"CDN$ 105.88"
      </script>
        
    <script>
    function Sale(price){
    this.price = price || 100;
    }
    Sale.prototype.getPrice = function(){
    return this.price;
    };
    //装饰者对象
    Sale.decorators = {};
     
    //装饰者从父对象获取值,然后再修改该值
    Sale.decorators.fedtax = {
    getPrice: function(){
    var price = this.uber.getPrice();
    price += price * 0.005;
    return price;
    }
    };
    Sale.decorators.quebec = {
    getPrice: function(){
    var price = this.uber.getPrice();
    price += price * 0.075;
    return price;
    }
    };
    Sale.decorators.money = {
    getPrice: function(){
    return "$" + this.uber.getPrice().toFixed(2);
    }
    };
    Sale.decorators.cdn = {
    getPrice: function(){
    return "CDN$" + this.uber.getPrice().toFixed(2);
    }
    };
     
    Sale.prototype.decorator = function(decorator){
    var F = function(){},
    overrides = this.constructor.decorators[decorator],
    i, newobj;
    F.prototype = this;
     
    newobj = new F();
    newobj.uber = F.prototype;
    for(i in overrides){
    if(overrides.hasOwnProperty(i)){
    newobj[i] = overrides[i];
    }
    }
    return newobj;
    };
     
    var sale = new Sale(100);
    sale = sale.decorator("fedtax");//增加联邦税
    sale = sale.decorator("quebec");//增加省税
    sale = sale.decorator("money");//以美元形式展示
    console.log(sale.getPrice());//"$112.88"
     
    //使用不同的税收策略
    var sale = new Sale(100);
    sale = sale.decorator("fedtax");//增加联邦税
    sale = sale.decorator("cdn");//以cdn形式展示
    console.log(sale.getPrice());//"CDN$ 105.88"
      </script>

    5,策略模式
















    欢迎转载,但转载请注明原文链接[博客园: http://www.cnblogs.com/jingLongJun/]
    [CSDN博客:http://blog.csdn.net/mergades]。
    如相关博文涉及到版权问题,请联系本人。
  • 相关阅读:
    那些容易忽略的事4-(正则表达式反向引用 )
    那些容易忽略的事3-(变量提升和函数提升)
    那些容易忽略的事(2)
    那些容易忽略的事(1) -变量与运算符+
    call()与apply()传参需要注意的一点
    CSS凹型导航按钮
    动态的99乘法表
    js中的for-of循环遍历数组
    交换2个变量的值
    gl.disableVertexArray P77 关闭location指定的attribute变量
  • 原文地址:https://www.cnblogs.com/jingLongJun/p/4491075.html
Copyright © 2020-2023  润新知