体是一个用来划分命名空间并将一些相关的属性与方法组织在一起的对象,如果她可以被实例化的话,那她只能被实例化一次(她只能嫁一次,不能二婚)。

单体模式是javascript里面最基本但也是最有用的模式之一。

特点:1. 可以用来划分命名空间,从而清除全局变量所带来的危险或影响。

   2. 利用分支技术来来封装浏览器之间的差异。

     3. 可以把代码组织的更为一体,便于阅读和维护。

单体模式的基本写法:

/* 最基本的单体模式 */
var her = {
   name: 'Anna',
   sex: 'women',
   say: function(){
        // 一些处理逻辑......
   },
   doing: function(){
        // 另一些处理函数......
    }
}

 1. 划分命名空间:

var box = {
    width: 0,
    height: 0,
    getArea: function(){
         return this.width * this.width; // js中对象成的访问必须是显示的,即this是不能省略的
    },
    init: function(w, h){
         // width = w;
         // height = h;这种方式相当于定义了两个全局变量,(没加var声明的变量为全局变量)
         // 并不是对对象width和height的赋值
         // 下面是正确的
         this.width = w;
         this.height = h;
    }
} //box划分了一个命名空间,命名空间里的变量只在空间里有效

上面的单体中的所有的成员以及方法都是公有的(public),也就是在单体的外部可以对她们进行任意的改动(但不能访问其中的局部变量),那为什么说单体提供了一个命名空间呢?

别急,我们接着往下看:

var box = {
        width:0,
        height:0,//单体的变量
        getArea:function(){
            return width * height;// width,height其实并不是单体的变量,而是在init中定义的全局变量
        }
        init:function(w,h){
            width = w;
            height = h;
        }
}// init中width,height其实并不是单体的变量
window.onload = function(){
    var init = box.getArea();
    alert(init);
}

由于没有对init中的width,height进行初始化,所以会报错,这样改一下:

var box = {
        width:0,
        height:0,
        getArea:function(){
            return width * height;
        },
        init:function(w,h){
            width = w;
            height = h;
        }
    }
window.onload = function(){
        width = 0;
        height = 0;
        //or box.init(0,0);
        var init = box.getArea();
    alert(init);
}

发现可以了,由于init和 getArea所用的width和height并不是归单体所有的变量,而是一个全局变量,所以我们可以在单体外面进行随意调用而不受影响、

var box = {
        width: 0,
        height: 0,
        getArea: function(){
            return width * height;//js中对象成的访问必须是显示的,即this是不能省略的
        },
        init:function(w,h){
            width = w;
            height = h;
        }
    }//这里的width,height其实并不是单体的对象
window.onload = function(){
        width = 0;
        height = 0;
        var width = box.getArea();
        alert(width);
}

这样写又会报错了,可见我们以上的方式对于全局变量并没有建立起一个命名空间,全局变量为我们带来了危险。所以最上面的写法是对的,我们来验证一下:

var box = {
        width: 2,
        height: 2,
        getArea: function(){
            return this.width * this.height;/ /js中对象成的访问必须是显示的,即this是不能省略的
        },
        init:function(w,h){
            this.width = w;
            this.height = h;
        }
    }
window.onload = function(){
        width = 0; // 不会影响单体中的局部变量也就是命名空间
        height = 0; // 不会影响单体中的局部变量也就是命名空间
        var width = box.getArea();
        alert(width);
}

可见在window.onload中的width 和height已经没有干扰了,因为单体为单体中的width和height建立了一个命名空间。

2. 成员的属性:

虽然在javascript中没有这么严格的面向对象(oop),但是我们可以借助闭包来进行一个模仿,毕竟有的变量设为public是很不好的。

var her = (function(){
    var name  = 'Anna';
    var sex = 'women';
    return {
         getArea: function(){
             return name + 'is a'  + sex;
         },
         init:function(b){
               name = b;
         }
    }
})();

window.onload = function(){
    her.name = 'Jock'; // 无法访问
    alert(ger.getArea());
    her.init('Lous');
    alert(her.getArea());
}

私有变量、方法是只读的,公有变量、方法是可读可写的。

访问:
对于私有成员,直接访问即可,前面不用加任何修饰,
对于公有的访问在单体作用域内前面要加上“this.”,在单体作用域外前面要加上“her.”(单体名字.)

3.利用分支技术来来封装浏览器之间的差异

注意的地方:

  a. 一定要用闭包,实现即时绑定

  b. 每个分支之间用分号隔开

  c. 最后返回的是分支的名字

  d. 调用的时候用单体名+分支的方法名;

// 利用单体的分支技术来定义XHR(XMLHttpRequest)对象,必须要用闭包才可以实现
var XHR = (function(){
    //The three branches
    var standard = {
        cXHR:function(){
                return new XMLHttpRequest();
            }
    };
    var activeXNew = {
        cXHR:function(){
                return new ActiveXObject('Msxml2.XMLHttp');
            }
    };
    var activeXOld = {
        cXHR:function(){
                return new ActiveXObject('Microsoft.XMLHttp');
            }
    };
    //To assign(分配) the branch, try each method;return whatever doesn't fail
    var testObject;
    try{
        testObject = standard.cXHR();
        return standard;// return this branch if no error was thrown
    }catch(e){
        try{
            testObject = activeXNew.cXHR();
            return activeXNew;
        }catch(e){
            try{
                testObject = activeXOld.cXHR();
                return activeXOld;
            }catch(e){
                throw new Error('Create the XMLHttpRequestObject failed!');
            }
        }
    }
})();
window.onload = function(){
    alert(XHR.cXHR());
}

共同进步吧!!!话说又星期五了

javascript --- 设计模式之单体模式(一)的更多相关文章

  1. javascript设计模式之单体模式

    一入前端深似海,刚入前端,以为前端只是div+css布局外加jquery操作DOM树辣么简单.伴随着对前端学习的深入,发现前端也是博大精深,而且懂得越多,才发现自己越无知,所以一定不能停下脚步的学习. ...

  2. javascript设计模式(单体模式)

    主要内容: js中最基本.应用最广的模式就是单体模式,实现原理是将代码组织为一个逻辑单元,这个逻辑单元中的代码可以通过单一的变更进行访问,确保对象只存在一份实例. 单体模式的特点: 在网页中使用全局变 ...

  3. Javascript设计模式(2)-单体模式

    单体模式 1. js最简单的单体模式 对象字面量:把一批有一定关联的方法和属性组织在一起 // 对象字面量 var Singleton = { attr1: true, attr2: 10, meth ...

  4. javascript --- 设计模式之单体模式(二)

    在JavaScript里,实现单例的方式有很多种,其中最简单的一个方式是使用对象字面量的方法,其字面量里可以包含大量的属性和方法: var her = { property1: 'someing', ...

  5. JS设计模式——5.单体模式

    JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html   单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...

  6. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  7. JS设计模式之单体模式(Singleton)

    单体模式作为一种软件开发模式在众多面向对象语言中得到了广泛的使用,在javascript中,单体模式也是使用非常广泛的,但是由于javascript语言拥有其独特的面向对象方式,导致其和一些传统面向对 ...

  8. 从ES6重新认识JavaScript设计模式(三): 建造者模式

    1 什么是建造者模式? 建造者模式(Builder)是将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示. 建造者模式的特点是分步构建一个复杂的对象,可以用不同组合或顺序建造出不 ...

  9. JavaScript 设计模式之----单体(单例)模式

    设计模式之--单体(单例)模式 1.介绍 从本章开始,我们会逐步介绍在JavaScript里使用的各种设计模式实现,在这里我不会过多地介绍模式本身的理论,而只会关注实现.OK,正式开始. 在传统开发工 ...

随机推荐

  1. NetBPM的安装 -转

    NetBPM的安装还是比较简单的,有比较详细的文档. 1.当然是先下载运行程序了, netbpm-0.8.3.1.zip ,官方网站:http://www.netbpm.org:2.然后解压后自己看 ...

  2. C# 类型基础——你可能忽略的技术细节

    引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone 其实也就是对象复制.复制又分为了浅度 ...

  3. SNF开发平台WinForm之十二-发送手机短信功能调用-金笛-SNF快速开发平台3.3-Spring.Net.Framework

    1.调用前组装参数 2.调用发送信息服务脚本   .调用前组装参数: BaseSendTaskEntity entity = new BaseSendTaskEntity(); entity.Mess ...

  4. ruby 除法运算

    在Ruby中根据运算对象的值的不同进行不同的操作.除法运算符"/"的两边同为Interger对象时运算符进行整除运算,其中任意一方为Float对象时进行实数的除法运算. 7 / 2 ...

  5. 如何将ToolBar 样式设置Title文字水平居中

    以下是我的activity.xml的代码,线性布局.<android.support.v7.widget.Toolbar         android:id="@+id/toolba ...

  6. Transactional replication 的Snapshot 文件在什么情况下会被清除

    Snapshot agent负责收集publication database的信息,将article的内容存储在snapshot文件中.而distribuiton cleanup job(后文简称清除 ...

  7. Hadoop入门进阶课程3--Hadoop2.X64位环境搭建

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博主为石山园,博客地址为 http://www.cnblogs.com/shishanyuan  ...

  8. 20款优秀的国外 Mobile App 界面设计案例

    在下面给大家分享的移动应用程序界面设计作品中,你可以看到不同创意类型的视觉效果.如果你想获得灵感,那很有必要看看下面20个优秀用户体验的移动应用 UI 设计.想要获取更多的灵感,可以访问移动开发分类, ...

  9. iOS-微信支付(订单号重复的问题)

    1. 官方文档中说过同一笔交易不能多次提交,出现这个错误让核实商户订单号是否重复提交,但是有些情况下是需要重复提交的,比如:用户微信支付的时候没有付款,直接取消了,那么订单如果已经创建了,在订单中心就 ...

  10. Direct3D11学习:(二)基本绘图概念和基本类型

    转载请注明出处:http://www.cnblogs.com/Ray1024   一.概述 在正式开始学习D3D11之前,我们必需首先学习必要的基础知识. 在这篇文章中,我们将介绍一下Direct3D ...