javascript 设计模式之单体模式 面向对象学习基础


Posted in Javascript onApril 18, 2010

单体模式(singleton)

单体是在脚本加载时创建的,能将一系列有关联的变量和方法组织为一个逻辑单元,逻辑单元里面的内容通过单一的变量进行访问;

一个单体主要分为三部分

用于访问内部信息的入口变量(如:Sky)
属性(如:nickName/age/timeInfo)
方法(如:sayHello)

基本结构

var Sky = { /* 
* 作用一,变量管理 
*/ 
nickName: "sky", 
age: "26", 
/* 
* 作用二,加载中初始化变量 
* 在加载过程中执行并初始化Sky.info 
*/ 
timeInfo: function() 
    { 
var _year = new Date().getFullYear(); 
return _year; 
}(), 
/* 
* 作用三,函数管理,让你的函数看起来不再那么散乱 
*/ 
sayHello: function() 
    { 
alert("hello,world!"); 
} 
} 
//所有内部信息通过Sky这个变量进行访问; 
alert(Sky.timeInfo);

以下是更详细的说明,看完了这篇文章,相信你应该差不多了解了,网上好多高手的js写法了,单体模式很常用。

单体是一个用来划分命名空间并将一批相关的属性和方法组织在一起的对象,如果他可以被实例化,那么他只能被实例化一次。
单体模式是javascript里面最基本但也是最有用的模式之一。
特点:

. 可以来划分命名空间,从而清除全局变量所带来的危险。
. 利用分支技术来来封装浏览器之间的差异。
. 可以把代码组织的更为一体,便于阅读和维护。

单体的基本结构(正确写法):

/*Basic Singleton*/ 
var Singleton = { 
attribute1:true, 
attribute2:10, 
method1:function(){}, 

 method2:function(){} 
};

划分命名空间:
var box = { 
width:0, 
height:0, 
getArea:function(){ 
return this.width*this.height;//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建立了一个命名空间。

成员的属性:

讨论完命名空间,我们来对单体变量和方法的属性做一下设定。学过其他语言的人(java,c++,c#...)都应该很了解其中类成员的public和private,
虽然在javascript中没有这么严格的面向对象(oop),但是我们可以借助闭包来进行一个模仿,毕竟有的变量设为public是很不好的。

var circle = (function(){ 
//pravite member! 
var r = 5; 
var pi = 3.1416;//后面用分号 
return{//public member 
getArea:function(){ 
return r*r*pi;//访问私有成员不要加this 
},//后面用逗号 
//如果想改变r和pi的值,只能通过设置一个公有的函数来实现 
init:function(setR){ 
r = setR; 
} 
} 
})() 
window.onload = function(){ 
circle.r = 0;//无法访问私有成员,相当于又为circle创建了一个共有成员r 
alert(circle.getArea()); 
circle.init(0);//通过公有的工具函数便可以访问了。 
alert(circle.getArea()); 
};

私有变量、方法是只读的,公有变量、方法是可读可写的
访问:
对于私有成员,直接访问即可,前面不用加任何修饰,
对于公有的访问在单体作用域内前面要加上“this.”,在单体作用域外前面要加上“circle.”(单体名字.)

呵呵,似乎有点味道了!
.利用分支技术来来封装浏览器之间的差异
注意的地方:
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 call 函数的用法说明
Apr 09 Javascript
jQuery切换所有复选框选中状态的方法
Jul 02 Javascript
JavaScript对数组进行随机重排的方法
Jul 22 Javascript
javascript实现3D变换的立体圆圈实例
Aug 06 Javascript
JS把内容动态插入到DIV的实现方法
Jul 19 Javascript
jQuery组件easyui基本布局实现代码
Aug 25 Javascript
javascript+html5+css3自定义提示窗口
Jun 21 Javascript
BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤
Aug 07 Javascript
通过vue-router懒加载解决首次加载时资源过多导致的速度缓慢问题
Apr 08 Javascript
JS二级菜单不同实现方法分析【4种方法】
Dec 21 Javascript
Vue computed 计算属性代码实例
Apr 22 Javascript
如何手写简易的 Vue Router
Oct 10 Javascript
js 获取子节点函数 (兼容FF与IE)
Apr 18 #Javascript
几个比较实用的JavaScript 测试及效验工具
Apr 18 #Javascript
javascript JSON操作入门实例
Apr 16 #Javascript
javascript对象之内置对象Math使用方法
Apr 16 #Javascript
jQuery 类twitter的文本字数限制带提示效果插件
Apr 16 #Javascript
jQuery maxlength文本字数限制插件
Apr 16 #Javascript
一款js和css代码压缩工具[附JAVA环境配置方法]
Apr 16 #Javascript
You might like
php学习 函数 课件
2008/06/15 PHP
PHP易混淆知识整理笔记
2015/09/24 PHP
PHP中STDCLASS用法实例分析
2016/11/11 PHP
PHP+JS实现的商品秒杀倒计时用法示例
2016/11/15 PHP
thinkphp5引入公共部分header、footer的方法详解
2018/09/14 PHP
php源码的使用方法讲解
2019/09/26 PHP
jquery实现固定顶部导航效果(仿蘑菇街)
2013/03/21 Javascript
jQuery之选项卡的简单实现
2014/02/28 Javascript
node.js中的forEach()是同步还是异步呢
2015/01/29 Javascript
JavaScript编程中容易出BUG的几点小知识
2015/01/31 Javascript
js实现用户离开页面前提示是否离开此页面的方法(包括浏览器按钮事件)
2015/07/18 Javascript
使用OpenLayers3 添加地图鼠标右键菜单
2015/12/29 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
2016/02/23 Javascript
轻松掌握JavaScript装饰者模式
2016/08/27 Javascript
Angularjs自定义指令Directive详解
2017/05/27 Javascript
微信小程序滑动选择器的实现代码
2018/08/10 Javascript
express框架下使用session的方法
2019/07/31 Javascript
浅谈Node新版本13.2.0正式支持ES Modules特性
2019/11/25 Javascript
使用cx_freeze把python打包exe示例
2014/01/24 Python
Python实现竖排打印传单手机号码易撕条
2015/03/16 Python
python中字符串类型json操作的注意事项
2017/05/02 Python
Python实现对百度云的文件上传(实例讲解)
2017/10/21 Python
python+pyqt5实现KFC点餐收银系统
2019/01/24 Python
详解Django CAS 解决方案
2019/10/30 Python
在Django中自定义filter并在template中的使用详解
2020/05/19 Python
Python数据可视化实现漏斗图过程图解
2020/07/20 Python
HTML5 绘制图像(上)之:关于canvas元素引领下一代web页面的问题
2013/04/24 HTML / CSS
英国家喻户晓的折扣商场:TK Maxx
2017/05/26 全球购物
进修护士自我鉴定
2013/10/14 职场文书
酒店七夕情人节活动策划方案
2014/08/24 职场文书
幼儿园园长工作总结2015
2015/05/25 职场文书
幼儿园托班开学寄语(2016秋季)
2015/12/03 职场文书
(开源)微信小程序+mqtt,esp8266温湿度读取
2021/04/02 Javascript
用Python可视化新冠疫情数据
2022/01/18 Python
Android RecyclerView实现九宫格效果
2022/06/28 Java/Android
详解CSS3浏览器兼容
2022/12/24 HTML / CSS