专栏首页wfacebossJavaScript设模式---单例模式

JavaScript设模式---单例模式

单例模式也称为单体模式,其中:

1,单体模式用于创建命名空间,将系列关联的属性和方法组织成一个逻辑单元,减少全局变量。  逻辑单元中的代码通过单一的变量进行访问。

2,三个特点:  ① 该类只有一个实例;  ② 该类自行创建该实例,即在该类内部创建自身的实例对象;  ③ 向整个系统公开这个实例接口

3,单体模式有四种基本形式:

第一种,最简单的单体,只被实例化一次    我简记为json对象

(1)基本结构

 var userInfo={//已经自行被实例化  其实是一json对象
        name:"测试名称",
        dept:"测试PD",
        code:"测试PD001",
        getName:function () {
            return "测试"
        }
    };

(2)使用方法与json的使用方法一致:使用点 " . "的方式访问

alert(userInfo.getName())

单体模式用来划分命名空间,并将一群相关的属性和方法组织到一起的简单介绍:

 var  comm={};//一个空对象


    comm.userInfo={//空对象下的第一个命名空间
        name:"命名空间1下的",
        code:"001"
    }

    comm.funcInfo={//空对象下的第二个命名空间
        funcName:"命名空间2下的",
        code:"002"
    }

总结:该种方式可以看出对象的变量值不是动态加载的,而且对象没有显示初始化,由此有了第二种单体模式。

第二种,具有局部变量的单体

要求:模拟一个使用ajax从数据库加载数据的过程

 (1)简单模拟一下ajax过程

//模拟一个Ajax操作
    function Ajax() {};//空对象
    //静态函数  模拟作为从数据库取值  此处值写死的
    Ajax.request=function (url,fn) {
        //默认永远回调成功
        if(true){
            fn("测试值1","测试值2")
        }
    }

(2)在最简单的单体中出现了数据不是动态从数据库加载的,而且没有显示实例化对象,此处使用闭包原理解决上述问题

//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
    var userInfo=(function () {
        //(1)利用闭包使单体有自己的私有局部变量
        var name="";
        var code="";
        //(2)利用ajax访问数据库取到数据
        Ajax.request("url",function (n,c) {//由于模拟的ajax中只是简单传递参数,所以第一个参数可以任意
                  name=n;
                  code=c;
        })
        //(3)单体实现私有变量的赋值
        return {
            name:name,
            code:code
        }
    })()

(3)使用该种方式的单体,不用实例化 可以直接返回一个单体 【因为使用userInfo时,直接return一个单体回来】

alert(userInfo.name);

总结:

(1)优点,灵活

(2)弊端:return 单体数据量比较大时,都需要从数据库取数据,每次加载都要执行,会影响程序性能。由于该种方式每次加载都要直接执行,return单体数据量大时会影响呈现的性能,于是有了第三种单体模式。

第三种,惰性单体 提供的解决方案为:调方法时才实例化单体,而不是加载时就执行。

于是在第二种的基础上进行修改为,

(1)模拟ajax从数据库加载数据不变

 //模拟一个Ajax操作
    function Ajax() {}
    //静态函数  模拟作为从数据库取值
    Ajax.request=function (url,fn) {
        //默认永远回调成功
        if(true){
            fn("测试值1","测试值2")
        }
    }

(2)动态从数据库加载数据 ,显示实例化,使用一个函数(Init())封装产生单体的函数,通过一个私有变量来返回函数(Init())

 //使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
    var UserInfo=(function () {

        var userInfo="";//私有变量

        function Init() {//在产生单体方式为包裹一层初始化函数
            //利用闭包使单体有自己的私有局部变量
            var name="";
            var code="";
            //利用ajax访问数据库取到数据
            Ajax.request("url",function (n,c) {
                name=n;
                code=c;
            })
            //单体
            return {
                name:name,
                code:code,
            }
        }

        return {//此时开始调用初始化函数实现单体的产生
            getInstance:function () {
                if(userInfo){//userInfo=""为false
                    return userInfo;
                }else {
                    userInfo=Init();
                    return userInfo;
                }
            }
        }

    })()

(3)使用   访问UserInfo对象里面的获取初始化获取对象的函数(getInstance())

   alert(UserInfo.getInstance().name);

总结:使用惰性单体实质上是通过对产生单体的函数进行再一次封装(使用函数封装),再在通过该类提供的唯一接口(getInstance()方法)访问初始化单体 的函数。

第四种,分支单体

简单的用处:做Ajax的时候根据不同的浏览器获得不同的XHR。(将浏览器之间的差异封装到动态方法,适用于解决浏览器之间的差异。)

比如下面一个简单的例子:在电脑不同分辨率的情况下初始化不一样的界面。(这里只是弹窗显示而已)

(1)获取电脑的分辨率

//得到机器的分辨率
    var screenWidth=window.screen.width;//width
    var screenHeight=window.screen.height;//height

(2)进行分支判断处理 ,将差异封装到动态方法中

  var portalInfo=(function () {
       //单体
     var $1280_1024={info:'1,2,3,5'}//单体1
     var $1366_768={info:'4,2,1,2'}//单体2

          //动态图选择浏览器的差异结果(这里是分辨率)
         if(screenWidth==1280){
             return $1280_1024;//返回单体进行初始化
         }else if(screenWidth==1366){
             return $1366_768;//返回单体进行初始化
         }else {
             throw  new Error("请检查你当前的电脑分辨率")
         }
     })();

(3)使用 ,获取最终的结果

alert(portalInfo.info)//我的结果为4,2,1,2 这是由于我的电脑的分辨率为1366*768

总结一下,对于分支单体有一个缺点:分支中,单体1和单体2都被创建了,并保存在内存中了,但只用到一个。需要在 计算时间 和 占用内存 两者中取舍。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ES6系列_9之对象

    有时候我们会在后台取出key值,而不是我们前台定义好的,这时候我们可以我们可以把后台定义的key值重新构建返回给后台。

    wfaceboss
  • JavaScript责任链模式

    责任链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将对象连成一条链,并沿着这...

    wfaceboss
  • 热词搜索_针对关键词的样式实现步骤

    wfaceboss
  • js内存泄漏常见的四种情况(From LeuisKen)

    本文主要选取了4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them 这篇文章中的一小...

    用户7657330
  • Dart 笔记 4 - 运算符

    condition ? expr1 : expr2 如果条件为真,则计算并返回 expr1 的值,否则计算并返回 expr2 的值。

    七适散人
  • mapboxGL之风流图

    前面的文章说到了Openlayers4中风场的实现,本文将讲述如何在mapbox GL实现类似的效果。

    lzugis
  • js倒计时,秒倒计时,天倒计时

    距某某开幕式还有 [<script language="JavaScript" type="text/javascript">djs()</script>] 天...

    用户3055976
  • JavaScript变量和数据类型

    变量 变量就是一个元素,类似于数学中的概念,用来指定表示一个对象。 在JavaScript中,用来指定变量的关键字为var。 当声明新变量时,可以使用关键词 "...

    静默虚空
  • 如何从高德获取地铁数据

    将浏览器console输出的内容拷贝下来,粘贴到一个文本里面,另存为geojson或者json均可。用QGIS打开并做简单的符号化即可得到如下效果。

    lzugis
  • AI大事件 | WaveNet推出了谷歌助手,苹果发布CoreML转换器

    大数据文摘

扫码关注云+社区

领取腾讯云代金券