1、单例模式:产生一个类的唯一实例
比如:点击按钮生成遮罩层->只生成一个div:先创建一个div,再调用->可能浪费:用变量判断->引入全局变量:用闭包包含->通用:单力包装器(桥接模式)
var singleton = function( fn ){ var result; return function(){ return result || ( result = fn .apply( this, arguments ) ); } } var createMask = singleton( function(){ return document.body.appendChild( document.createElement('div') ); })
2、桥接模式:实现与抽象分离
forEach的实现
forEach = function( ary, fn ){ for ( var i = 0, l = ary.length; i < l; i++ ){ var c = ary[ i ]; if ( fn.call( c, i, c ) === false ){ return false; } } }
3、简单工厂模式:由方法决定到底要创建哪个类的实例
比如:要创建三棵树,每棵树只是容器不同,所以把创建树的方法写一个函数,创建时传入容器就行
4、观察者模式(发布-订阅模式)
(function($){ var o = $({}); $.subscribe = function(){ o.on.apply(o, arguments); } $.unsubscribe = function(){ o.off.apply(o, arguments); } $.publish = function(){ o.trigger.apply(o, arguments); } })(jQuery) function handle(e, a, b, c){ console.log(a+b+c); } $.subscribe('sfp', handle); $.publish('sfp', ['a', 'b', 'c']);
太爽了,这应该可以解决不少问题。想不到离我这么近,需要publish才可以执行事件
5、适配器模式:很像转接口
比如:从后端传来的数据不能直接用在jsTree上,使用适配器模式,把数据转为jsTree的格式就行
设计模式是编程中的基础哲学,平时都没注意到,但无意中用了很多。
6、代理模式:为其他对象提供一种代理以控制对这个对象的访问
比如:一个对象只接受键盘事件,另一个对象负责组合键
比如:大叔 代理 dudu 给萧姑娘送花。http://www.cnblogs.com/TomXu/archive/2012/02/29/2354979.html
7、外观模式:提供一个高层接口,使得客户端更加方便调用
需要保证函数尽可能地处在一个合理粒度,提供给客户端一个高层接口,而不用管真正的细节
var stopEvent = function( e ){ //同时阻止事件默认行为和冒泡 e.stopPropagation(); e.preventDefault(); }
8、访问者模式:把一些可复用的行为抽象到一个函数里,如果一个对象要调用这个函数,只需要把对象当做参数传给这个函数:call或者apply
Array构造器和String构造器的prototype上的方法就被特意设计成了访问者。这些方法不对this的数据类型做任何校验。这也就是为什么arguments能冒充array调用push方法.
9、策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换
var dataSourceVendor = { xml : { get : function(){ console.log("XML数据源") ; } } , json : { get : function(){ console.log("JSON数据源") ; } } , csv : { get : function(){ console.log("CSV数据源") ; } } } ; console.log("选择的数据源:" + dataSourceVendor["json"]["get"]()) ;
10、模板方法模式:预先定义一组算法,先把算法的不变部分抽象到父类,再将另外一些可变的步骤延迟到子类去实现。
工厂模式的意图是根据子类的实现最终获得一种对象. 而模版方法模式着重于父类对子类的控制.
11、中介者模式:让各个对象之间不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互
区别:代理模式中A必然是知道B的一切,而中介者模式中A,B,C对E,F,G的实现并不关心.而且中介者模式可以连接任意多种对象。
12、迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该方法中的内部表示。
iterator
13、组合模式:部分-整理模式,将所有对象组合成树形结构。使得用户只需要操作最上层的接口,就可以对所有成员做相同的操作
比如:想取消所有节点上绑定的事件:$('body').unbind('*')
14、备忘录模式:数据缓存
比如一个分页控件, 从服务器获得某一页的数据后可以存入缓存。以后再翻回这一页的时候,可以直接使用缓存里的数据而无需再次请求服务器。
var Page = function(){ var page = 1, cache = {}, data; return function( page ){ if ( cache[ page ] ){ data = cache[ page ]; render( data ); }else{ Ajax.send( 'cgi.xx.com/xxx', function( data ){ cache[ page ] = data; render( data ); }) } } }()
这种函数内定义变量,再return function的用法很常见,单例模式?
15、职责链模式:js中的事件冒泡就是作为一个职责链来实现的。一个事件在某个节点上被触发,然后向根节点传递, 直到被节点捕获。
16、享元模式:减少程序所需的对象个数,可以提供一些共享的对象以便重复利用.
原理其实很简单, 把刚隐藏起来的div放到一个数组中, 当需要div的时候, 先从该数组中取, 如果数组中已经没有了, 再重新创建一个. 这个数组里的div就是享元, 它们每一个都可以当作任何用户信息的载体.
handsontable是不是也可以使用享元模式,时smooth scroll时不会缓慢
17、状态模式:状态模式主要可以用于这种场景:1 一个对象的行为取决于它的状态;2 一个操作中含有庞大的条件分支语句
var StateManager = function(){ var currState = 'wait'; var states = { jump: function( state ){ }, wait: function( state ){ }, attack: function( state ){ }, crouch: function( state ){ }, defense: function( state ){ if ( currState === 'jump' ){ return false; //不成功,跳跃的时候不能防御 } //do something; //防御的真正逻辑代码, 为了防止状态类的代码过多, 应该把这些逻辑继续扔给真正的fight类来执行. currState = 'defense'; // 切换状态 } } var changeState = function( state ){ states[ state ] && states[ state ](); } return { changeState : changeState } } var stateManager = StateManager(); stateManager.changeState( 'defense' );
写的真好!
http://blog.jobbole.com/29454/