上一回聊到JS中模拟接口,装饰者模式,掺元类,分析了backbone的继承源码,感受还好吧!javascript
介一回,偶们来聊一下在JS单例模式(singleton),单例模式其实运用很普遍,好比:jquery,AngularJS,underscore吖虾米的都是单例模式,来吧,直接开始咯:java
保证一个类只有一个实例,从全局命名空间里提供一个惟一的访问点来访问该对象。其实以前写过的对象字面量也是一种简单单例,以下:jquery
var Singleton = { name: "飞狐", method: function () { return 'hello world'; } }; alert(Singleton.method()); // 返回hello world
这就是一个简单单例了,应该不少盆友已经看出来了,没有做用域,若是要扩展私有属性和方法的话,那么就能够靠闭包来实现。android
顾名思义要用到闭包,做为返回实例对象,以下:web
var Singleton = (function(){ var name = '飞狐'; // 私有属性 var nickname = '帅狐'; var showNickname = function(){ // 私有方法 return nickname; } return { // 返回一个对象 name:name, // 将私有属性公开 nickName: function(){ // 在公开的方法中返回私有方法 return showNickname(); } } })(); alert(Singleton.name); // 飞狐 alert(Singleton.nickName()); // 帅狐
这里咱们接着上边儿简单单例的例子来,稍微的改一下,改为闭包以后,就数据保证了不受外界干扰了。windows
惰性单例就是只有在使用的时候才初始化,以下:浏览器
var Singleton = (function(){ var uniq; // 私有变量,用来存放返回实例化对象的容器 function init(){ // 初始化方法 var buildeList = function(){ // 私有方法 // 下面这一堆就是建立一个有序列表,含有5个li var root = document.createElement('ol'); document.body.appendChild(root); for(var i=0;i<5;i++){ var a = document.createElement('a'); a.innerHTML = '<a>帅狐</a>'; var li = document.createElement('li'); li.appendChild(a); root.appendChild(li); } } return { // 同样的闭包,暴露共有方法 method:function(){ return buildeList(); } }; } return { // 这里就是实例化对象了 getInstance:function(){ // 这里的uniq为true的时候,或者能够写成 typeof uniq==='undefined' if(!uniq){ // 建立单例实例 uniq = init(); } return uniq; } }; })(); Singleton.getInstance().method(); // 返回1.帅狐2.帅狐3.帅狐4.帅狐5.帅狐
这个例子就是惰性单例了,也就是说只有在用的时候才会去初始化方法,这样能够更省资源。闭包
分支单例就很简单了,就是作程序分支的判断,利用分支来返回相应的实例,常常用于浏览器检测,直接看代码吧,以下:app
var ua = window.navigator.userAgent.toLocaleLowerCase(); var matchedRE = /iphone|android|symbianos|windows\sphone/g; var Singleton = (function() { var webUrl = 'web端url'; var mobileUrl = '移动端url'; return (matchedRE.test(ua))?mobileUrl:webUrl; })(); // 若是是pc端返回就是web端url,若是是移动端就返回移动端url alert(Singleton);
这个例子就是分支单例了,比较简单,这个例子也是模拟京东目前判断访问设备的代码。iphone
装个逼再说。刚看到一新闻,韩雪发微博称,由于本身修改的本月套餐,上月流量就清零了,并称:“我改这个月的和上个月有什么关系吗?我付了钱的,多余的流量凭什么你说清零就清零呢?这不是霸王条款吗?”,女神都忍受不了了,哈哈~~
这一回讲的内容很少,就一个单例模式,
下面的内容更简单,一道题。
function calculate(str){ //命名一个变量放置字母出现的最高次数并初始化为0 var maxLength = 0; //命名一个变量放置结果输入 var result = ''; //循环迭代开始,并判断字符串是否为空 while(str != '' ){ //将原始的字符串变量赋值给新变量 var oldStr = str; //用字符串的substr的方法获得第一个字符(首字母) var getStr = str.substr(0,1); //执行一次全局替换 eval("str = str.replace(/"+getStr+"/g,'')"); //判断原始的字符串的长度减去替代后字符串长度是否大于以前出现的最大的字符串长度 if(oldStr.length-str.length > maxLength ) { //两字符串长度相减获得最大的字符串长度 maxLength = oldStr.length-str.length; //返回最大的字符串结果(字母、出现次数) result = "出现最多的字母是:" + getStr + "------出现了" + maxLength + " 次。"; } } return result; } var str ="adadfdfseffserfefsefseeffffftsdg"; alert(calculate(str));
这个题基本上我都写了注释,难度适中,当娱乐消遣。
这一回,主要聊了单例模式,应该很好理解,难度不大。
下一回,咱主要聊一聊工厂模式。
话说,看完文章以为ok,客观点个赞呗,好东西多推荐推荐,让你们都知道,嘿嘿,好像有点那啥卖瓜了...
注:此系飞狐原创,转载请注明出处