一、面向对象编程
二、创建型设计模式
一类处理对象创建的模式,通过某种方式控制对象的创建来避免基本对象创建时可能导致设计上的问题或增加设计上的复杂度。
1.简单工厂模式
静态工厂方法,由一个工厂对象决定创建某一种产品对象的实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| var LoginAlert = function(text){ this.content = text; } LoginAlert.prototype.show = function(){ } var LoginConfirm = function(text){ this.content = text; } LoginConfirm.prototype.show = function(){ } var LoginPrompt = function(text){ this.content = text; } LoginPrompt.prototype.show = function(){ }
var PopFactory = function(name){ switch(name){ case 'alert': return new LoginAlert(); case 'confirm': return new LoginConfirm(); case 'prompt': return new LoginPrompt(); } }
function createPop(type,text){ var o = new Object(); o.content = text; o.show = function(){ }; if(type==='alert'){ } if(type==='prompt'){ } if(type==='confirm'){ } return o; } var usernamealert = createPop('alert','用户名只能是26个字母');
|
2.工厂方法模式
通过对产品类的抽象使其创建业务主要负责用于创建多累产品的实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| var Factory = function(type,content){ if(this instanceof Factory){ var s = new this[type](content); return s; }else{ return new Factory(type,content); } } Factory.prototype = { Java:function(content){ }, Javascript:function(content){ }, UI:function(content){ this.content = content; (function(content){ var div = document.createElement('div'); div.innerHTML = content; div.style.border = '1px solid #ccc'; document.getElementById('container').appendChild(div); })(content); } ... } var data = [ {type:'Java',content:'...'}, {type:'Javascript',content:'...'}, {type:'UI',content:'...'}, ] for(var i = 6;i>=0;i--){ Factory(s[i].type,s[i].content); }
|
3.抽象工厂模式
通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建某一类产品的实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| var VehicleFactory = function(subType,supperType){ if(typeof VehicleFactory[subType] === 'function'){ function F(){}; F.prototype = new VehicleFactory[subType](); subType.constructor = subType; subType.prototype = new F(); }else{ throw new Error('未创建该抽象类'); } }
VehicleFactory.Car = function(){ this.type = 'car'; }; VehicleFactory.Car.prototype = { getPrice:function(){ return new Error('抽象方法不能调用'); }, getSpeed:function(){ return new Error('抽象方法不能调用'); } }
VehicleFactory.Car = function(){ this.type = 'bus'; }; VehicleFactory.Bus.prototype = { getPrice:function(){ return new Error('抽象方法不能调用'); }, getSpeed:function(){ return new Error('抽象方法不能调用'); } }
VehicleFactory.Truck = function(){ this.type = 'truck'; }; VehicleFactory.Car.prototype = { getPrice:function(){ return new Error('抽象方法不能调用'); }, getSpeed:function(){ return new Error('抽象方法不能调用'); } }
var BMW = function(price,speed){ this.price = price; this.speed = speed; } VehicleFactory(BMW,'car'); BMW.prototype.getPrice = function(){ return this.price; } BMW.prototype.getSpeed = function(){ return this.speed; }
|
4.建造者模式
Builder将一个复杂对象的构建层与其表示层相互分离。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| var Human = function(param){ this.skill = param && param.skill || '保密'; this.hobby = param && param.hobby || '保密'; }
Human.prototype = { getSkill:function(){ return this.skill; }, getHobby:function(){ return this.hobby; } }
var Named = function(name){ var that = this; (function(name,that){ that.woleName = name; if(name.indexOf(' ')>-1){ that.FirstName = name.slice(0,name.indexOf(' ')); that.SecondName = name.slice(name.indexOf(' ')); } })(name,that); } var Work = funciton(work){ var that = this; (function(work,that){ switch(work){ case 'code': that.work = '工程师'; that.workDescript = 'programer'; case 'UI': that.work = '设计师'; that.workDescript = 'designer'; default : that.work = work; that.workDescript = 'sorry'; } })(work,that) }
Work.prototype.changeWork = function(work){ this.work = work; }
Work.prototype.changeDescript = function(setence){ this.changeDescript = setence; }
|
创建一位应聘者
1 2 3 4 5 6 7 8 9
| var Person = function(name,work){ var _person = new Human(); _person.name = new Named(name); _person.work = new Work(work); return _person; }
var person = new Person('lee','code');
|
5.原型模式
Prototype用原型实例指向创建对象的类,使用于创建新的对象的类共享 原型对象的属性及方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| var LoopImages = function(imgArr,container){ this.imageArray = imgArr; this.container = container; } LoopImages.prototype = { createImage: fucntion(){ }, changeImage: fucntion(){ } } var SlideLoopImg = function(imgArr,container){ LoopImages.call(this,imgArr,container) } SlideLoopImg.prototype = new LoopImages();
SlideLoopImg.prototype.changeImage = function(){ console.log("changeImage fn"); } var FadeLoopImg = function(imgArr,container,arrow){ LoopImages.call(this,imgArr,container) this.arrow = arrow; } FadeLoopImg.prototype = new LoopImages(); FadeLoopImg.prototype.changeImage = function(){ console.log("changeImage fn"); }
LoopImages.prototype.getImageLength = function(){ return this.imagesArray.length; } LoopImages.prototype.getContainer = function(){ return this.container; }
|
6.单例模式
单体模式,只允许实例化一次的对象类。
命名空间,namespace
1 2 3 4 5 6 7 8
| var Ming = { g: function(id){ return document.getElementById(id); }, css: function(id,key,value){ this.g(id).style[key] = value; } }
|
小型代码库
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var A = { Util:{ util_methods1 : function(){}, util_methods2 : function(){} }, Tool:{ tool_methods1 : function(){}, tool_methods2 : function(){} }, Ajax:{ get : function(){}, post : function(){} } }
|
无法修改的静态变量
1 2 3 4 5 6 7 8 9 10 11 12
| var Conf = (function(){ var conf = { NUM:1, COUNT:100 } return { get:function(name){ return conf[name] ? conf[name] : null; } } }) Conf.get('COUNT');
|
惰性单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var LazySingle = function(){ var instance = null function Single(){ return { publicMethod : function(){}, publicProperty : '1.0' } }' return function(){ if(!_instance){ _instance = Single(); } return _instance; } } //test LazySingle().publickProperty; // 1.0
|
三、结构型设计模式
关注如何将类或对象组合成更大、更复杂的架构,以简化设计
1.外观模式
为一组复杂的子系统接口提供一个更高级的统一接口,使访问更容易。底层结构兼容性做统一的简化用户使用。
addEventListener && attachEvent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function addEvent(dom,type,fn){ if(dom.addEventListener){ dom.addEventListener(type,fn,false); }else if(){ dom.attachEvent("on"+type,fn); }else{ dom['on'+type] = fn; } }
var myInput = document.getElementById('myinput'); addEvent(myInput,'click',function(){ console.log('绑定的第一个事件'); }) addEvent(myInput,'click',function(){ console.log('绑定的第二个事件'); })
|
e.preventDefault && e.target
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| var getEvent = function(event){ return event || window.event; }
var getTarget = function(event){ var event = getEvent(event); return event.target || event.srcElement; }
var preventDefault = function(event){ var event = getEvent(event); if(event.preventDefault){ event.preventDefault(); }else{ event.returnValue = false; } }
document.onclick=function(e){ preventDefault(e); if(getTarget(e) !== document.getElementById('myInput')){ hideInputSug(); } }
|
小型代码库
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var A = { g: fucntion(id){ return docuemnt.getElementById(id); }, css: fucntion(id,key,value){ docuemnt.getElementById(id)[key] = value; }, html: fucntion(id,html){ docuemnt.getElementById(id).innerHtml = html; } }
A.css('box','background','red');
|
2.适配器模式
将一个类的接口转化成另一个接口,以满足用户需求,使类之间接口的不兼容问题通过适配器得以解决。
参数适配器
1 2 3 4 5 6 7 8 9 10 11 12 13
| function doSomeThing(obj){ var _adapter = { name:'', title:'', age:'', color:'', size:100, prize:50 } for(var i in _adapter){ _adapter[i] = obj[i] || _adapter[i]; } }
|
数据适配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| var obj = { name:'', age:'', job:'' } function arrToObjAdapter(arr){ return { name:arr[0], age:arr[1], job[2] } } var test = arrToObjAdapter[obj]; console.log(test);
function ajaxAdapter(data){ return [data['key1'],data['key2'],data['key3']]; } $.ajax.... { doSomeThing(ajaxAdapter(res)); }
|
3.代理模式
由于一个对象不能直接引用另一个对象 ,所以需要通过代理对象 在这2个对象之间起到中介的作用。
跨域
1.同一域名不同的端口号 http://www.baidu.com:8081 http://www.baidu.com:8082
2.同一域名不同协议 http://www.baidu.com https://www.baidu.com
3.域名和域名对应的IP http://www.baidu.com http://10.10.10.10
4.主域和子域 http://www.baidu.com http://xx.baidu.com
5.子域和子域 http://tieba.baidu.com http://fanyi.baidu.com
script代理 和 JSONP
4.装饰者模式
在不改变原对象的基础上,通过对其进行包装拓展使原有对象可以满足用户的更复杂需求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| var decorator = function(input,fn){ var input = document.getElementById(input); if(typeof input.onclick === 'function'){ var oldClickFn = input.onclick; input.onclick = function(){ oldClickFn(); fn(); } }else{ input.onclick = fn; } }
decorator('tel_input',function(){ document.getElementById('tel_demo_text').style.display = 'none'; })
|
5.桥接模式
在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦。
实现层(元素绑定的事件)和抽象层(如修饰页面UI逻辑)解耦分离,使两部分可以独立变化。
- 提取共同点:相同逻辑代码提取处理
1 2 3 4
| function changeColor(dom,color,bg){ dom.style.color = color; dom.style.background = bg; }
|
- 桥接:事件与业务 逻辑之间的桥梁:需要用一个方法将他们链接起来
1 2 3 4 5 6
| spans[0].onmouseover = function(){ changeColor(this,'red','#ddd'); } spans[0].onmouseout = function(){ changeColor(this,'#333','#f5f5f5'); }
|
6.组合模式
又称部份-整体模式,将对象组合成树形结构以表示部份整体的层次结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| var News = function(){ this.children = []; this.element = null; } News.prototype = { init:funticon(){ throw new Error('请重写你的方法'); }, add:funticon(){ throw new Error('请重写你的方法'); }, getElement:funticon(){ throw new Error('请重写你的方法'); } }
var Container = function(id,parent){ News.call(this); this.id = id; this.parent = parent; this.init(); }
inheritPrototype(Container,News);
Container.prototype.init = function(){ this.element = document.createElement('ul'); this.element.id = this.id; this.element.className = 'new-container'; }
Container.prototype.add = function(child){ this.children.push(child); this.element.appendChild(child.getElement()); return this; }
Container.prototype.getElement = function(){ return this.element; }
Container.prototype.show = function(){ this.parent.appendChild(this.element); }
var news1 = new Container('news',document.body); news1.add( ).add( )
|
7.享元模式
运用共享技术有效地支持大量的颗粒度的对象,避免对象间拥有相同内容造成多余的开销。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| var Flyweight = function(){ var created = []; function create(){ var dom = document.createElement('div'); document.getElementById('container').appendChild(dom); created.push(dom); return dom; } return { getDiv: function(){ if(created.length<5){ return create(); }else{ var div = created.shift(); created.push(div); return div; } } } }
|
四、行为型设计模式
用于不同对象 之间职责划分或算法的抽像,不仅涉及类和对象,还涉及类或对象之间的交流模式并加以实现
1.模板方法模式
父类中定义一组操作算法骨架,而将一些实现步骤延迟到子类中,使得子类可以不改变父类的算法结构的同事可重新定义算法中某些实现步骤。(封装 弹出框方法 或提示框的思路)
2.观察者模式
又称作发布-订阅模式或消息机制,定义了一种依赖关系,解决主体对象 与观察者之间的功能耦合。
1 2 3 4 5 6 7 8 9
| var Observer = (function(){ var _message = {}; return { regist:function(){}, fire:function(){}, remove:function(){}, } })();
|
3.状态模式
当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| var MarryState = function(){ var _currentState = {}; var states = { jump:function(){}, move:function(){}, shoot:function(){}, squat:function(){}, } var Action = function(){ changeState:function(){ var arg = arguments; _currentState = {}; 如果有动作就添加动作 if(arg.length){ for(var i = 0;i<arg.length;i++){ _currentState[arg[i]] =true; } } return this; }, goes: function(){ for(var i in currentState){ states[i] && states[i](); } return this; } } return { change:Action.changeState, goes:Action.goes } }
MarryState() .change('jump','shoot') .goes() .goes()
var marry = new MarryState(); marry .change('jump','shoot') .goes() .goes()
|
4.策略模式
将定义的一组算法封装起来,使其相互之间可以替换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var priceStrategy = function(){ var stragtegy = { return30 :function(price){}, return50 :function(price){}, percent90 :function(price){}, } return function(algorithm,price){ return stragtegy[algorithm] && stragtegy[algorithm](price) } }
var price = priceStrategy('return50','314'); console.log(price);
|
5.职责链模式
解决请求的发送者与请求的接受者之间的耦合,通过职责上的多个对象 对分解请求流程,实现请求在多个对象之间传递,直到最后一个对象完成请求的处理。
- 请求模块
- 响应数据适配模块
- 创建组件模块
- 单元测试
6.命令模式
将请求与实现解耦,并封装成独立对象,从而使不同的请求对客户端的实现参数化。
例如:将执行的命令封装,解决命令发起者与命令执行者之间的耦合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| var canvasCMD = (function(){ var canvas = document.getElementById('canvas'); ctx = canvas.getContext('2d'); var Action = { fillStyle : function(c){ ctx.fillStyle = c; }, fillRect : function(x,y,width,height){ ctx.fillRect(x,y,width,height); }, } return { excute:function(msg){ if(!msg) return; if(msg.length){ for(var i=0;i<msg.length;i++){ arguments.callee(msg[i]); } }else{ msg.param = Object.prototype.toString.call(msg.param) === '[Object Array]'? msg.param : [msg.param]; Action[msg.command].apply(Action,msg.param); } } } })();
|
7.访问者模式
针对于对象结构中的元素,定义在不改变此对象的前提下访问结构中元素的新方法。
解决数据与数据的操作方法之间的耦合,将数据的操作方法独立于数据,使其可以自由变化。
1 2 3 4 5 6 7 8
| var Visitor = (function(){ reutrn{ splice:function(){}, push:function(){}, pop:function(){}, } })();
|
8.中介者模式
通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用,降低他们之间的耦合。
同观察者模式一样,中介者模式的主要业务也是通过模块间或者对象间的通信 ,来解决模块间或对象间的耦合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| var Mediator = function(){ var _msg = {}; return { register:function(type,action){ if(_msg[type]){ _msg[type].push(action); }else{ _msg[type] = []; _msg[type].push(action); } }, send:function(type){ if(_msg[type]){ for(var i = 0;i<_msg[type].length;i++){ _msg[type][i] && _msg[type][i](); } } } } }();
|
9.备忘录模式
在不破坏对象的封装性的前提下,在对象之外铺货并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态。
主要针对现有的数据或状态做为缓存,为将来某个时刻使用或恢复做准备。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var Paget = function{ var cache = {}; return function(page,fn){ if(cache[page]){ showPage(page,cache[page]); fn && fn(); }else{ $.post((),{ showPage(page,res.data); cache[page] = res.data; fn && fn(); }) } } }();
|
10.迭代器模式
在不暴露对象 内部结构的同时,可以顺序地访问聚合对象内部的元素。
优化循环语句的一种可行方案,它使得程序清晰易读。可以顺序的访问一个聚合对象中的每一个元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var Iterator = function(items,container){ var container = container && document.getElementById(container) || document, items = container.getElementByTagName(items), length = item.length, index = 0; var splice = [].splice; return { first : function(){}, second : function(){}, pre : function(){}, next : function(){}, get : function(){}, dealEach : function(){}, dealItem : function(){}, exclusive : function(){}, } }
|
11.解释器模式
对于一种语言,给出其文法表示形式,并定义一种解释器,通过使用这种解释器来解释语言中定义的句子。
对客户提出的需求,经过解析而形成的一个抽象解释程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var Interpreter = (function(){ function getSublingName(node){} return function(node,wrap){ var path = []; var wrap = wrap || document; if(node===wrap){ if(wrap.nodeType == 1){ path.push(wrap.nodeName.toUpperCase()); return path; } } return path; } })();
|
五、技巧型设计模式
通过一些特定技巧来解决组件的某些方面的总理,这些技巧一般通过实践经验总结得到。
1.链模式
通过在对象方法中将当前对象返回,实现对同一个对象多个方法的链式调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| var A = function(selector){ return new A.fn.init(selector); }
A.fn = A.prototype = { constructor:A, init:function(selector){ } } A.fn.init.prototype = A.fn;
A.fn.extend({ on:(function(){ })() }) A.fn.extend({ css:(function(){ })() })
A('div') .css({ }) .on('click',function(){ })
|
2.委托模式
多个对象 接收 并处理同一个请求,他们将请求委托给另一个对象 统一处理请求。
通过委托者将请求给被委托者去处理实现,解决了请求与委托者之间的耦合。
还能解决内存泄露(IE旧浏览器)
1 2 3 4 5 6 7 8 9
| $.get("./deal.php?g=banner",function(res){ }) $.get("./deal.php?g=news",function(res){ }) $.get("./deal.php?g=member",function(res){ })
|
数据分发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var Deal ={ banner:function(){ }, news:function(){ }, member:function(){ } } $.get('./deal.php?',fucntion(res){ for(var i in res){ Deal[i] && Deal[i](res[i]) } })
|
3.数据访问对象模式
抽象和封装数据源的访问与存储,DAO通过对数据源链接的管理方便对数据的访问与存储。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| var BaseLocalStorage = function(preId,timeSign){ this.preId = preId; this.timeSign = timeSign || '|-|'; }
BaseLocalStorage.protorype = { status:{ SUCCESS : 0, FAILURE : 1, OVERFLOW : 2, TIMEOUT : 3 }, storage: localStorage || window.localStorage, getKey: function(key){ return this.preId + key; }, set: function(key,value,callback,time){ }, get: function(key,callback){ }, remove: function(key,callback){ } }
|
4.节流模式
对重复的业务逻辑进行节流控制,执行最后一次操作并取消其它操作,以提高性能。
- 清除将要执行的函数,传递两个参数(是否清除,执行函数)。如果true,则表示清除将要执行的函数,同时会判断第二个参数有没有计时器句柄,有则清除计时器。
- 延迟执行函数(执行函数,相关参数)。在节流器内部首先要为执行函数绑定一个计时器句柄,来保存该执行函数的计时器;相关参数包括执行函数在执行时的作用域,执行函数的参数,执行函数延迟执行的时间。
- 适用于:返回顶部、浮层、图片延迟加载….
5.简单模板模式
通过格式化字符串拼凑出视图避免创建视图时大量字点操作。优化内存开销。
DOM操作创建视图造成大量消耗。正则方式去格式化字符串更好。
目前已经有成熟的模板第三方,当然底层的模板生成器原理也是非常重要的知识。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| A.view = function(name){ var v = { code: '<pre><code> {#code#} </code></pre>', img: '<img src="{#src#}" alt="{#alt#}" title="{#title#}">', part: '<div id="{#id#}">{#part#}</div>' } if(Object.prototype.toString.call(name)==="[object Array]"){ var tpl = ''; for(var i=0,len=name.length;i<len;i++){ tpl += arguments.callee(name[i]); } return tpl; }else{ return v[name] ? v[name] : ('<'+name+'>{#'+name+'#}</'+name+'>'); } }
|
6.惰性模式
减少每次代码执行时的重复性分支判断,通过对对象重定义来屏蔽原对象中的分支判断。
这是一种拖延模式,由于对象的创建或者数据的计算会花费高昂的代价,因此页面之处会延迟对这一类对象的创建。
- 文件加载后立即执行对象方法来冲定义对象
- 当第一次使用对象时重新定义对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| A.on = function(dom,type,fn){ if(document.addEventListener){ return function(dom,type,fn){ dom.addEventListener(type,fn,false); } } else if(document.attachEvent){ return function(dom,type,fn){ dom.attachEvent('on'+type,fn); } } else { return function(dom,type,fn){ dom('on'+type) = fn; } } }();
A.on = function(dom,type,fn){ if(document.addEventListener){ A.on = function(dom,type,fn) dom.addEventListener(type,fn,false); } } else if(document.attachEvent){ A.on = function(dom,type,fn) dom.attachEvent('on'+type,fn); } } else { A.on = function(dom,type,fn) dom('on'+type) = fn; } } // 执行重新定义on方法 A.on(dom,type,fn); }
|
7.参与者模式
在特定的作用域中执行给定的函数,并将参数原封不动地传递。
重点:函数绑定和函数柯理化
后期重点学习
8.等待着模式
通过对多个异步进程的监控,来触发未来发生的动作。
主要处理耗时比较长的操作。提供回调方案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| var Waiter = function(){ var dfd = [], doneArr = [], failArr = [], slice = Array.prototype.sclice, that = this; var Primise = function(){ this.resolved = false; this.rejected = false; } Primise.prototype = { resolve: function(){i this.resolved = true; if(!dfd.length) return; for(var i =dfd.length-1;i>=0;i--){ if(dfd[i]&&!dfd[i].resolved || dfd[i].rejected){ return; } } dfd.slice(i,1); _exec(doneArr); }, reject: function(){ this.rejected = true; if(!dfd.length) return; dfd.slice(0); _exec(failArr); } } that.Deferred = function(){ return new Promise(); } function _exec(arr){ var i = 0,len = arr.length; for(;i<len;i++){ try{ arr[i] && arr[i](); }catch(e){} } } that.when = function(){ dfd = slice.call(arguments); var i = dfd.length; for(--i,i>=0;i--){ if(!dfd[i] || dfd[i].resolved || dfd[i].rejected || !dfd[i] instanceof Primise){ dfd.slice(i,1); } } return that; }; that.done = function(){ doneArr = doneArr.concat(slice.call(arguments)); return that; }; that.fail = function(){ failArr = failArr.concat(slice.call(arguments)); return that; }; }
|
六、架构型设计模式
是一类框架 结构,通过提供一些子系统,指定他们的职责,并将他们条理清楚地组织在一起。
已经有非常成熟的框架,只作简要概述,底层原理查看相关页码。
1.同步模块模式
模块化:将复杂的系统分解成高内聚、低耦合的模块 ,使系统开发变得可控、可维护、可拓展,提高模块 的复用率。
同步模块模式:SMD 请求发出后,无论模块是否存在,立即执行后续的逻辑,实现模块开发中对模块的立即引用。分而治之。
底层原理:P255
2.异步模块模式
异步模块模式:AMD请求发出后,继续其他业务 逻辑,知道模块加载完成执行后续逻辑,实现模块开发中对模块加载完成后的引用。
底层原理:P255
将页面分解成部件,针对部件开发,最终组合成完整的页面。
1 2 3 4 5 6 7 8
| F.moudule('lib/template',function(){ var _TplEngine = function(){}, _getTpl = function(){}, _dealTpl = function(){}, _compileTpl = function(){} return _TplEngine; })
|
4.MVC模式
model view controller 将业务逻辑、数据、视图分离的方式组织架构代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| var MVC = MVC || {};
MVC.model = function(){ var M = {}; M.data = {}; M.conf = {}; return { getData:function(m){ return M.data[m]; }, getConf:function(c){ return M.conf[c]; }, setData:function(m,v){ M.data[m] = v; return this; }, setConf:function(c){ M.data[c] = v; return this; }, } }();
MVC.view = function(){ var M = MVC.model; var V = {}; return function(v){ V[v]; } }();
MVC.controller = function(){ var M = MVC.model; var V = MVC.view; var C = {}; }();
|
5.MVP模式
模型 视图 管理器Presenter。View不直接引用Model的数据,而是通过presenter实现对model层的数据访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ~(function(window){ var MVP = function(){}; MVP.model = function(){}; MVP.view = function(){}; MVP.presenter = function(){ var V = MVP.view; var M = MVP.model; var C = {}; return { init: function(){ for(var i in C){ C[i] && C[i][M,V,i]; } } } }; MVP.init = function(){}; window.MVP = MVP; })(window)
|
6.MVVM模式
模型 - 视图 - 视图模型 (VM)
底层原理:P298