js装饰者模式

js装饰者模式:

装饰者对象都将以构造函数的属性这种方式来实现

Alt text

function Sale(price){
    this.price = price || 100;
}
Sale.prototype.getPrice = function(){
    return this.price;
};
Sale.decorators =  {
    fedtax : {
        getPrice:function(){
            var price = this.uber.getPrice();
            price += price * 5 / 100;
            return price;
        }
    },
    quebec : {
        getPrice : function(){
            var price = this.uber.getPrice();
            price += price * 7.5 / 100;
            return price;
        }
    },
    money : {
        getPrice : function(){
            return '$' + this.uber.getPrice().toFixed(2);
        }
    },
    cdn : {
        getPrice : function(){
            return 'CDN$ ' + this.uber.getPrice().toFixed(2);
        }
    }
};
Sale.prototype.decorate = function(decorator){
    var F = function(){},
        overrides = this.constructor.decorators[decorator],
        i,newobj;
    console.log(this);
    F.prototype = this;  //除了第一次,每一次this的值都上一次的一个构造函数F的实例
    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.decorate('fedtax');
sale = sale.decorate('quebec');
//sale = sale.decorate('money');
sale = sale.decorate('cdn');
sale.getPrice();  //先找到cdn的getPrice方法,依次再找this.uber.getPrice(),直到Sale.prototype.getPrice的方法,再从最内到往逐个运行

下面是最后newobj的原型结构

newobj: F
getPrice: function (){
    arguments: null
    caller: null
    length: 0
    name: ""
    prototype: Sale.decorators.cdn.getPrice        //cdn
    __proto__: function Empty() {}
    <function scope>
    uber: F
    __proto__: F
    getPrice: function (){
        arguments: null
        caller: null
        length: 0
        name: ""
        prototype: Sale.decorators.quebec.getPrice     //quebec
        constructor: function (){
        __proto__: Object
        __proto__: function Empty() {}
        <function scope>
        uber: F
        __proto__: F
        getPrice: function (){
            arguments: null
            caller: null
            length: 0
            name: ""
            prototype: Sale.decorators.fedtax.getPrice      //fedtax
            __proto__: function Empty() {}
            <function scope>
            uber: Sale
            __proto__: Sale
            price: 100
            __proto__: Sale          //Sale.prototype.getPrice
            constructor: function Sale(price){
            decorate: function (decorator){
            getPrice: function (){
            __proto__: Object

还有一种使用列表来实现,这种方法更为简单,也不涉及继承,也更易于理解

Alt text

var Sale = function (price){
    this.price = (price > 0 ) || 100;  //this.price为true的时候,在运算当中会作为1来处理,如果为false的时候,在参与参与去处的过程当中会作为0来处理
    this.decorators_list = [];
};
Sale.prototype.decorate = function(decorator){
    this.decorators_list.push(decorator);
};
Sale.prototype.getPrice = function(){
    var price = this.price, i,
        max = this.decorators_list.length,name;
    for(i=0;i<max;i++){
        name = this.decorators_list[i];
        price = Sale.decorators[name].getPrice(price);
    }
    return price;
};
Sale.decorators = {
    fedtax : {
        getPrice : function(price){
            return price + price * 5 / 100;
        }
    },
    quebec : {
        getPrice : function(price) {
            return price + price * 7.5 / 100;
        }
    },
    money :{
        getPrice : function(price){
            return '$' + price.toFixed(2);
        }
    }
};
var sale = new Sale(100);
sale.decorate('fedtax');
sale.decorate('quebec');
sale.decorate('money');
sale.getPrice();

js工厂模式与迭代器模式

js工厂模式:

  • 设计工厂模式的目的是为了创建对象
  • 它通常在类或者类的静态方法中实现

Alt text

function CarMaker(){}
CarMaker.prototype.drive = function(){
    return "Vroom,I have "+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.SUV = function(){
    this.doors = 24;
};

总结:该工厂模式是通过构造函数自身的静态方法factory,为该构造函数的其它的静态方法创建实例,创建的这些实例的原型是继承自本身的构造函数(new CarMaker())。

js迭代器模式:

在迭代器模式中,通常有一个包含数据集合的对象。
该数据可能存储在一个复杂数据结构内部,而要提供一种简单的方法能够访问数据结构中每个元素。

Alt text

var agg = (function(){
    var index = 1,
        data = [1,2,3,4],
        lenght = data.length,
        direction,
        symbol;
    return {
        nextPrev:function(opt){
            direction = opt.direction || '';

            if(!this.hasNext() || !direction){
                return null;
            }
            //执行动作
            index = eval(index+symbol+1);
        },
        hasNext:function(){
            if(direction=='next'){
                symbol = '+';
                return index < lenght;
            }
            if(direction=='prev'){
                symbol = '-';
                return index > 1;
            }
        },
        current:function(){
            return index;
        },
        rewind:function(){
            index = 0;
        }
    }
})();

agg.nextPrev({direction:'next'});
agg.nextPrev({direction:'prev'});
agg.current();
agg.rewind();