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 相关文章推荐
checkbox设置复选框的只读效果不让用户勾选
Aug 12 Javascript
jquery根据name属性查找的小例子
Nov 21 Javascript
如何从jQuery的ajax请求中删除X-Requested-With
Dec 11 Javascript
jquery删除提示框弹出是否删除对话框
Jan 07 Javascript
浅析jQuery中调用ajax方法时在不同浏览器中遇到的问题
Jun 11 Javascript
JavaScript必知必会(七)js对象继承
Jun 08 Javascript
多种方式实现js图片预览
Dec 12 Javascript
cordova入门基础教程及使用中遇到的一些问题总结
Nov 14 Javascript
小程序接口的promise化的实现方法
Dec 11 Javascript
vue实现把接口单独存放在一个文件方式
Aug 13 Javascript
JavaScript常用工具函数库汇总
Sep 17 Javascript
基于jQuery拖拽事件的封装
Nov 29 jQuery
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学习之PHP变量
2006/10/09 PHP
Nigma vs Alliance BO5 第一场2.14
2021/03/10 DOTA
ExtJS 2.0实用简明教程 之Ext类库简介
2009/04/29 Javascript
script标签的 charset 属性使用说明
2010/12/04 Javascript
jquery 元素控制(追加元素/追加内容)介绍及应用
2013/04/21 Javascript
JS操作Cookies的小例子
2013/10/15 Javascript
Node.js实用代码段之获取Buffer对象字节长度
2016/03/17 Javascript
jQuery操作属性和样式详解
2016/04/13 Javascript
JS中递归函数
2016/06/17 Javascript
jQuery回到顶部的代码
2016/07/09 Javascript
AngularJs入门教程之环境搭建+创建应用示例
2016/11/01 Javascript
WebView启动支付宝客户端支付失败的问题小结
2017/01/11 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
2017/03/15 Javascript
jQueryeasyui 中如何使用datetimebox 取两个日期间相隔的天数
2017/06/13 jQuery
详解在微信小程序的JS脚本中使用Promise来优化函数处理
2019/03/06 Javascript
vue-cli3 项目优化之通过 node 自动生成组件模板 generate View、Component
2019/04/30 Javascript
vue页面引入three.js实现3d动画场景操作
2020/08/10 Javascript
python使用递归解决全排列数字示例
2014/02/11 Python
python3制作捧腹网段子页爬虫
2017/02/12 Python
jupyter notebook参数化运行python方式
2020/04/10 Python
使用Django搭建网站实现商品分页功能
2020/05/22 Python
使用SQLAlchemy操作数据库表过程解析
2020/06/10 Python
html5仿支付宝密码框的实现代码
2017/09/06 HTML / CSS
马来西亚时装购物网站:ZALORA马来西亚
2017/03/14 全球购物
STAY JAPAN台湾:预订日本民宿
2018/07/22 全球购物
日本乐天官方海外转运服务:Rakuten Global Express
2018/11/30 全球购物
Shell脚本如何向终端输出信息
2014/04/25 面试题
销售演讲稿范文
2014/01/08 职场文书
三年级语文教学反思
2014/02/01 职场文书
需求分析说明书
2014/05/09 职场文书
入职担保书范文
2014/05/21 职场文书
论文答辩开场白大全
2015/05/27 职场文书
于丹讲座视频观后感
2015/06/15 职场文书
珍爱生命主题班会
2015/08/13 职场文书
2015年党务工作者个人工作总结
2015/10/22 职场文书
2016春季幼儿园开学寄语
2015/12/03 职场文书