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

单体模式(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());
}

最后再啰嗦几句:
对于单体据说是最常用的模式之一了,至于利弊嘛要在实践中慢慢的体会了,由于本人也是初学,所以没有太多的发言权,不足指出还忘高手指教

时间: 2024-07-30 16:51:16

javascript 设计模式之单体模式 面向对象学习基础_js面向对象的相关文章

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

单体是一个用来划分命名空间并将一些相关的属性与方法组织在一起的对象,如果她可以被实例化的话,那她只能被实例化一次(她只能嫁一次,不能二婚). 单体模式是javascript里面最基本但也是最有用的模式之一. 特点: 1. 可以用来划分命名空间,从而清除全局变量所带来的危险或影响. 2. 利用分支技术来来封装浏览器之间的差异. 3. 可以把代码组织的更为一体,便于阅读和维护. 单体模式的基本写法: /* 最基本的单体模式 */ var her = { name: 'Anna', sex: 'wom

学习JavaScript设计模式之迭代器模式_javascript技巧

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. JavaScript中的Array.prototype.forEach 一.jQuery中的迭代器 $.each([1, 2, 3], function(i, n) { console.log("当前下标为:"+ i + " 当前元素为:"+ n ); }); 二.实现自己的迭代器 var each = function(ary, callback) { for(var i

JavaScript中实现单体模式分享_javascript技巧

单体模式作为一种软件开发模式在众多面向对象语言中得到了广泛的使用,在javascript中,单体模式也是使用非常广泛的,但是由于javascript语言拥有其独特的面向对象方式,导致其和一些传统面向对象语言虽然在单体模式的思想上是一致的,但是实现起来还是有差异的. 首先来看看传统面向对象语言对于单体模式的定义:单体模式是只能被实例化一次并且可以通过一个众所周知的访问点来访问的类.这个定义有两点突出了传统面向对象语言的特征,即类和实例化,所以对于传统面向对象语言来讲,单体模式是建立在其类和实例化的

JavaScript设计模式之策略模式

在网上搜索"为什么MVC不是一种设计模式呢?"其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选择学习策略模式. 策略模式:定义了一系列家族算法,并对每一种算法单独封装起来,让算法之间可以相互替换,独立于使用算法的客户. 通常我并不会记得"牛顿第一定律"的具体内容,所以我也难保证我会对这个定义记得多久--用FE经常见到的东西来举个例子说明一下: $("d

JavaScript设计模式之工厂模式和构造器模式_javascript技巧

什么是模式 前阵子准备期末考试,劳神又伤身的,实在闲不得空来更新文章,今天和大家说说javascript中的设计模式. 首先呢,我们需要知道的是:模式是一种可复用的解决方案,而反模式呢就是针对某个问题的不良解决方案. js反模式常见例子 1.向setTimeout和setInterval传递字符串,而不是函数,这会触发eval()的内部使用. 2.在全局上下文中定义大量的变量污染全局命名空间 3.修改Object类的原型 4.以内联形式使用js,嵌入在HTML文件中的js代码是无法包含在外部单元

学习JavaScript设计模式之代理模式_javascript技巧

明星都有经纪人作为代理.如果请明星办一场商演,只能联系其经纪人,经纪人会把商演的细节和报酬谈好,再把合同交给明星签. 一.定义 代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问. 代理分为:保护代理和虚拟代理 保护代理:用于控制不同权限的对象对目标对象的访问,在JavaScript中很难判断谁访问了某个对象,所以保护代理很难实现. 二.图片预加载(最常见的虚拟代理应用场景) 图片预加载是一种常用技术,如果直接给某个img标签节点设置src属性,由于图片过大或者网络不佳,图片的位置往

学习JavaScript设计模式之策略模式_javascript技巧

把不变的部分和变化的部分隔开是每个设计模式的主题. 条条大路通罗马.我们经常会遇到解决一件事情有多种方案,比如压缩文件,我们可以使用zip算法.也可以使用gzip算法.其灵活多样,我们可以采用策略模式解决. 一.定义 定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 基于策略类模式的程序至少由两部分组成.第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程.第二个部分是环境类Context,Context接收客户的请求,随后把请求委托给某一个策略类. 二.示例 计

学习JavaScript设计模式之状态模式_javascript技巧

状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变. 当电灯开着,此时按下开关,电灯会切换到关闭状态:再按一次开关,电灯又将被打开.同一个开关在不同的状态下,表现出来的行为是不一样的. 一.有限状态机 状态总数(state)是有限的. 任一时刻,只处在一种状态之中. 某种条件下,会从一种状态转变(transition)到另一种状态. 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类. 解释: (1)将状态封装成独立的类,并将请求委托给当前的状态对

学习JavaScript设计模式之模板方法模式_javascript技巧

一.定义 模板方法是基于继承的设计模式,可以很好的提高系统的扩展性. java中的抽象父类.子类 模板方法有两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类. 二.示例 Coffee or Tea (1) 把水煮沸 (2) 用沸水浸泡茶叶 (3) 把茶水倒进杯子 (4) 加柠檬 /* 抽象父类:饮料 */ var Beverage = function(){}; // (1) 把水煮沸 Beverage.prototype.boilWater = function() { conso