资讯专栏INFORMATION COLUMN

听飞狐聊JavaScript设计模式系列06

hiYoHoo / 1800人阅读

本回内容介绍

上一回聊到JS中模拟接口,装饰者模式,掺元类,分析了backbone的继承源码,感觉还好吧!

介一回,偶们来聊一下在JS单例模式(singleton),单例模式其实运用很广泛,比如:jquery,AngularJS,underscore吖虾米的都是单例模式,来吧,直接开始咯:

1. 单例模式

保证一个类只有一个实例,从全局命名空间里提供一个唯一的访问点来访问该对象。其实之前写过的对象字面量也是一种简单单例,如下:

    var Singleton = {
        name: "飞狐",
        method: function () {
            return "hello world";
        }
    };
    alert(Singleton.method());    // 返回hello world

这就是一个简单单例了,应该很多盆友已经看出来了,没有作用域,如果要扩展私有属性和方法的话,那么就可以靠闭包来实现。

2. 闭包单例模式

顾名思义要用到闭包,作为返回实例对象,如下:

    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());    // 帅狐 

这里我们接着上边儿简单单例的例子来,稍微的改一下,改成闭包之后,就数据保证了不受外界干扰了。

3. 惰性单例模式

惰性单例就是只有在使用的时候才初始化,如下:

    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 = "帅狐";
                    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.帅狐

这个例子就是惰性单例了,也就是说只有在用的时候才会去初始化方法,这样可以更省资源。

4. 分支单例模式

分支单例就很简单了,就是做程序分支的判断,利用分支来返回相应的实例,经常用于浏览器检测,直接看代码吧,如下:

    var ua  = window.navigator.userAgent.toLocaleLowerCase();
    var matchedRE = /iphone|android|symbianos|windowssphone/g;
    var Singleton = (function() {
          var webUrl = "web端url";
          var mobileUrl = "移动端url";
          return (matchedRE.test(ua))?mobileUrl:webUrl;
    })();
    // 如果是pc端返回就是web端url,如果是移动端就返回移动端url
    alert(Singleton); 

这个例子就是分支单例了,比较简单,这个例子也是模拟京东目前判断访问设备的代码。


装个逼再说。刚看到一新闻,韩雪发微博称,因为自己修改的本月套餐,上月流量就清零了,并称:“我改这个月的和上个月有什么关系吗?我付了钱的,多余的流量凭什么你说清零就清零呢?这不是霸王条款吗?”,女神都忍受不了了,哈哈~~

这一回讲的内容不多,就一个单例模式,
下面的内容更简单,一道题。

5. 笔试题:判断字符串中出现次数最多的字母,返回该字母及其出现次数
    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,客观点个赞呗,好东西多推荐推荐,让大家都知道,嘿嘿,好像有点那啥卖瓜了...

注:此系飞狐原创,转载请注明出处

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86126.html

相关文章

  • 飞狐JavaScript设计模式系列02

    摘要:本回内容介绍上一回聊到数据类型,简单的过了一遍,包括个数组新特性等,这一回来聊聊对象,结合数组来实战一些例子,在做题中成长,记忆会更深刻,来吧,开始咯创建实例的方式有两种使用操作符后跟构造函数飞狐使用对象字面量表示法飞狐也可以飞狐这种写法与 本回内容介绍 上一回聊到JS数据类型,简单的过了一遍,包括9个数组新特性等,这一回来聊聊Object对象,结合数组来实战一些例子,在做题中成长,记...

    tangr206 评论0 收藏0
  • 飞狐JavaScript设计模式系列11

    摘要:桥接模式之特权函数特权函数,用一些具有特权的方法作为桥梁以便访问私有空间,可以回忆一下之前的系列。连续自然数分组,计算最多组的个数将至这个连续自然数分成组使每组相加的值相等。个数组中数字最多的一组有个此时的和为。 本回内容介绍 上一回,聊了适配器模式,图片预加载,介一回,聊桥接模式(Bridge),跟之前一样,难度比较小,桥接模式将抽象部分与它的实现部分分离,通过桥接模式联系彼此,同时...

    wanglu1209 评论0 收藏0
  • 飞狐JavaScript设计模式系列10

    摘要:本回内容介绍上一回,聊了代理模式,虚拟代理,图片懒加载,介一回,也比较容易,适配器模式,用一个新的接口对现有类的接口进行包装,处理类与的不匹配。这一回,主要聊了适配器模式,图片预加载,主要还是理解下一回,聊一聊桥接模式,顺便做一做计算题。 本回内容介绍 上一回,聊了代理模式,虚拟代理,图片懒加载,介一回,也比较容易,适配器模式(Adapter),用一个新的接口对现有类的接口进行包装,处...

    yexiaobai 评论0 收藏0
  • 飞狐JavaScript设计模式系列14

    摘要:本回内容介绍上一回,聊了聊状态模式,并介绍了一下介一回,聊链式编程,模拟一下,再模拟一下封装一个库。这一回,主要聊了链式调用,模拟了,尤其是,希望大家能喜欢这次代码分享。下一回,聊一聊的策略模式。 本回内容介绍 上一回,聊了聊状态模式(State),并介绍了一下vue.js;介一回,聊链式编程,模拟一下jQuery,再模拟一下underscore.js,封装一个库。 1. 链式调用 (...

    fox_soyoung 评论0 收藏0
  • 飞狐JavaScript设计模式系列09

    摘要:说白了,就是对访问进行控制。这一回,主要聊了代理模式,虚拟代理,图片懒加载,难度适中下一回,聊一下适配器模式,难度也比较小。 本回内容介绍 上一回,聊了门面模式,DOM2级事件,事件委托,介一回,也比较容易,代理模式(proxy),代理对象控制对本体对象的访问,实现了同样的接口,并且会把任何方法的调用传递到本体对象。说白了,就是对访问进行控制。直接上代码,走你: 1.代理模式 代理也是...

    张春雷 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<