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 相关文章推荐
防止网站内容被拷贝的一些方法与优缺点好处与坏处分析
Nov 30 Javascript
javascript 通用简单的table选项卡实现
May 07 Javascript
js showModalDialog参数的使用详解
Jan 07 Javascript
jQuery实现异步获取json数据的2种方式
Aug 29 Javascript
js数值计算时使用parseInt进行数据类型转换(jquery)
Oct 07 Javascript
jQuery中scrollLeft()方法用法实例
Jan 16 Javascript
JS控制弹出新页面窗口位置和大小的方法
Mar 02 Javascript
微信小程序 MD5加密登录密码详解及实例代码
Jan 12 Javascript
详解如何使用微信小程序云函数发送短信验证码
Mar 13 Javascript
8 个有用的JS技巧(推荐)
Jul 03 Javascript
Vue中keep-alive组件作用详解
Feb 04 Javascript
vue修改Element的el-table样式的4种方法
Sep 17 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版
2006/10/09 PHP
NO3第三帝国留言簿制作过程
2006/10/09 PHP
基于Jquery的温度计动画效果
2010/06/18 Javascript
jQuery插件windowScroll实现单屏滚动特效
2015/07/14 Javascript
JS实现登录页面记住密码和enter键登录方法推荐
2016/05/10 Javascript
基于JS实现回到页面顶部的五种写法(从实现到增强)
2016/09/03 Javascript
第一次接触神奇的前端框架vue.js
2016/12/01 Javascript
jQuery实现页面倒计时并刷新效果
2017/03/13 Javascript
快速使用node.js进行web开发详解
2017/04/26 Javascript
vue2.0 根据状态值进行样式的改变展示方法
2018/03/13 Javascript
JavaScript实现简单动态进度条效果
2018/04/06 Javascript
Angular入口组件(entry component)与声明式组件的区别详解
2018/04/09 Javascript
js使用cookie实现记住用户名功能示例
2019/06/13 Javascript
解决微信小程序中的滚动穿透问题
2019/09/16 Javascript
layui默认选中table的CheckBox复选框方法
2019/09/19 Javascript
详解关于Vue单元测试的几个坑
2020/04/26 Javascript
JS+Canvas实现五子棋游戏
2020/08/26 Javascript
python字符串的方法与操作大全
2018/01/30 Python
Python实现的本地文件搜索功能示例【测试可用】
2018/05/30 Python
python 实现视频流下载保存MP4的方法
2019/01/09 Python
深度辨析Python的eval()与exec()的方法
2019/03/26 Python
Python虚拟环境的原理及使用详解
2019/07/02 Python
Django 多表关联 存储 使用方法详解 ManyToManyField save
2019/08/09 Python
对python中UDP,socket的使用详解
2019/08/22 Python
Python英文文章词频统计(14份剑桥真题词频统计)
2019/10/13 Python
Python使用selenium + headless chrome获取网页内容的方法示例
2019/10/16 Python
Jupyter notebook快速入门教程(推荐)
2020/05/18 Python
如何向scrapy中的spider传递参数的几种方法
2020/11/18 Python
python爬取微博评论的实例讲解
2021/01/15 Python
纯CSS3单页切换导航菜单界面设计的简单实现
2016/08/16 HTML / CSS
Html5 Geolocation获取地理位置信息实例
2016/12/09 HTML / CSS
英国最好的包装供应商:Priory Direct
2019/12/17 全球购物
介绍一下EJB的分类及其各自的功能及应用
2016/08/23 面试题
大宝sod蜜广告词
2014/03/21 职场文书
解除施工合同协议书
2014/10/17 职场文书
不尊敬老师的检讨书
2014/12/21 职场文书