js 设计模式

摘要:
出乎意料的是,事件只有在离我很近并且需要发布的时候才能执行。5.适配器模式:很像接口传输。例如,后端的数据不能直接用于jsTree。使用适配器模式将数据传输到jsTree格式是编程的基本理念。我平时没注意到,但我不小心用了很多。

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/  

  

免责声明:文章转载自《js 设计模式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CentOS7 复制文件夹和移动文件夹windows下vue项目启动步骤下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

通过Nginx设置HttpOnly Secure SameSite参数解决Cookie跨域丢失

在前面的文章中“谷歌浏览器Chrome80版本默认SameSite导致跨域请求Cookie丢失”,我们知道Chrome升级到80版本后,默认限制了跨域携带cookie给后端。将HttpOnly设置为true防止程序获取cookie后进行攻击。SameSite:Chrome浏览器在51版本后为Cookie新增的属性,用来防止CSRF攻击和用户追踪。不过,前提是...

TCL基本语法2

TCL基本语法21、format和scan两个基本的函数,和C语言中的sprintf和scanf的作用基本相同。format将不同类型的数据压缩在字符串中,scan将字符串中的数据提取出来。setnameJacksetage100setworker[format"%sis%dyearsold"$name$age]puts$workerscan$worker"...

virtuoso数据库的安装方法

数据库虚拟师有两种安装和配置方法。第一种方法是默认情况下直接在系统中安装virtualoso,复制virtualoso的安装文件,然后默认情况下将其直接安装。使用命令行对virtualoso数据库进行操作。1将virtualoso opensource解压缩到指定目录。例如,c:virtualoso2安装VC++2012和VC++2010插件补丁3以设置环境...

安装samba服务器实现Linux mint和Windows共享文件

安装samba服务器以实现Linuxmint和Windows共享文件。在Linuxmint普通用户下执行命令:sudoapt-geinstallsamba、installsamba和打开smb。conf配置文件,并执行命令gedit/etc/samba/smb-Coff,如果您想安装gedit(sudoapt-geinstallgedit),还可以使用Lin...

Innodb_large_prefix

但是,索引列的总长度不能超过3072字节的限制仍然存在...

微信分享之分享图片/分享图标不能显示

微信分享的分享图标/图片无法显示,主要是由于以下几个问题:1.确保分享界面调用成功,分享路径正确。2.确保共享图片的路径不使用中文或全半角字符。3.确保副本不包含敏感字符,如红包和收据。当共享接口未能成功加载时,将发生错误。在页面的前面使用隐藏的div来放置要制作缩略图的图片。记住,不能直接隐藏图片。style=“display:noen”,如果没有,则使用...