JavaScript模式读书笔记 第7章 设计模式
1,单例模式
-1,最简单的单例:
<script>//obj为单例var obj = {myProp: "My Value"};var obj1 = obj;var obj2 = obj;console.log(obj1 == obj2);//trueconsole.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);//trueconsole.log(u2.nothing);//trueconsole.log(u1.everything);//undefinedconsole.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);//trueconsole.log(u2.nothing);//trueconsole.log(u1.everything);//trueconsole.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);//trueconsole.log(n.constructor === Number);//trueconsole.log(s.constructor === String);//trueconsole.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());//1while(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]。
如相关博文涉及到版权问题,请联系本人。
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。

浙公网安备 33010602011771号