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/