JavaScript设计模式之单体模式全面解析


Posted in Javascript onSeptember 09, 2016

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

单体模式是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设计模式之单体模式全面解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JS实现简单的Canvas画图实例
Jul 04 Javascript
JavaScript中创建类/对象的几种方法总结
Nov 29 Javascript
jQuery 判断图片是否加载完成方法汇总
Aug 10 Javascript
jQuery实现仿QQ空间装扮预览图片的鼠标提示效果代码
Oct 30 Javascript
javascript超过容器后显示省略号效果的方法(兼容一行或者多行)
Jul 14 Javascript
AngularJs 指令详解及示例代码
Sep 01 Javascript
基于jquery实现二级联动效果
Mar 30 jQuery
vue-mugen-scroll组件实现pc端滚动刷新
Aug 16 Javascript
ES6中Set和Map用法实例详解
Mar 02 Javascript
基于小程序请求接口wx.request封装的类axios请求
Jul 02 Javascript
VUE动态生成word的实现
Jul 26 Javascript
Vue解决移动端弹窗滚动穿透问题
Dec 15 Vue.js
jQuery实现的超链接提示效果示例【附demo源码下载】
Sep 09 #Javascript
全面解析Bootstrap表单样式的使用
Sep 09 #Javascript
jQuery+ajax读取并解析XML文件的方法
Sep 09 #Javascript
JS与jQuery实现隔行变色的方法
Sep 09 #Javascript
jQuery层次选择器用法示例
Sep 09 #Javascript
jQuery基本过滤选择器用法示例
Sep 09 #Javascript
jQuery可见性过滤选择器用法示例
Sep 09 #Javascript
You might like
php中使用exec,system等函数调用系统命令的方法(不建议使用,可导致安全问题)
2012/09/07 PHP
PHP动态生成指定大小随机图片的方法
2016/03/25 PHP
PHP+MySQL存储数据常见中文乱码问题小结
2016/06/13 PHP
PHP有序表查找之插值查找算法示例
2018/02/10 PHP
解决Laravel5.2 Auth认证退出失效的问题
2019/10/14 PHP
层序遍历在ExtJs的TreePanel中的应用
2009/10/16 Javascript
基于jquery的textarea发布框限制文字字数输入(添加中文识别)
2012/02/16 Javascript
JS实现来回出现文字的状态栏特效代码
2015/10/31 Javascript
jQuery+css实现的时钟效果(兼容各浏览器)
2016/01/27 Javascript
MVC+jQuery.Ajax异步实现增删改查和分页
2020/12/22 Javascript
JS查找字符串中出现最多的字符及个数统计
2017/02/04 Javascript
jquery滚动条插件slimScroll使用方法
2017/02/09 Javascript
jQuery实现弹窗居中效果类似alert()
2017/02/27 Javascript
vue v-on监听事件详解
2017/05/17 Javascript
javascript 面向对象实战思想分享
2017/09/07 Javascript
解决vue-cli + webpack 新建项目出错的问题
2018/03/20 Javascript
JavaScript原型对象原理与应用分析
2018/12/27 Javascript
layui实现数据表格点击搜索功能
2020/03/26 Javascript
jquery获取input输入框中的值
2019/11/13 jQuery
vue使用nprogress加载路由进度条的方法
2020/06/04 Javascript
python基础教程之面向对象的一些概念
2014/08/29 Python
python 连接各类主流数据库的实例代码
2018/01/30 Python
python表格存取的方法
2018/03/07 Python
Python中使用Counter进行字典创建以及key数量统计的方法
2018/07/06 Python
使用Python实现在Windows下安装Django
2018/10/17 Python
Python常用扩展插件使用教程解析
2020/11/02 Python
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
Puccini乌克兰:购买行李箱、女士手袋网上商店
2020/08/06 全球购物
保送生自荐信范文
2013/10/06 职场文书
物流专业求职计划书
2014/01/10 职场文书
写自荐信三大法宝
2014/01/24 职场文书
导师就业推荐信范文
2014/05/22 职场文书
政府法律服务方案
2014/06/14 职场文书
国际政治学专业推荐信
2014/09/26 职场文书
护士个人年终总结
2015/02/13 职场文书
一条 SQL 语句执行过程
2022/03/17 MySQL