JavaScript单体模式:命名空间与私有成员实现详解

作者:异步漫步

时间:2026-10-30

浏览:169

本文深入解析JavaScript单体模式,阐述其作为命名空间划分工具的重要性。通过代码示例演示如何利用闭包实现私有变量与公有方法的封装,解决全局变量污染问题。同时介绍利用分支技术封装浏览器差异的标准写法,帮助开发者构建更清晰、易维护的JavaScript代码结构。

文章目录

单体模式概述与核心特点

单体模式是一种用于划分命名空间,并将相关属性与方法组织在一起的对象结构。其核心约束在于:若该对象允许实例化,则全局范围内仅能存在一个实例,确保唯一性。

在JavaScript开发中,单体模式被视为基础且极具实用价值的核心模式之一。

该模式主要具备以下特点:

第一,通过划分命名空间,有效消除全局变量可能引发的冲突或安全隐患。

第二,利用分支技术封装不同浏览器之间的实现差异,提升兼容性。

第三,使代码结构更加内聚,从而提升代码的可读性与后期维护效率。

单体模式的基础实现方式如下:


/* 最基本的单体模式 */ 
var her = {
name: 'Anna',
sex: 'women',
say: function(){
// 一些处理逻辑......
},
doing: function(){
// 另一些处理函数......
} 
}

命名空间的划分与实现

首先,进行命名空间的划分。


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建立了独立的命名空间,实现了隔离。

私有成员与公有成员的访问控制

其次,关注成员的属性访问控制。

虽然JavaScript并非严格的面向对象语言,但我们可以借助闭包机制来模拟私有成员的概念。将某些变量设为公有并非最佳实践,因此需要区分访问权限。


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.”前缀,而在单体作用域外部访问时,需加上“单体名.”前缀。

利用分支技术封装浏览器差异

第三,利用分支技术封装浏览器间的差异。

在使用分支技术时,需注意以下关键点:

a. 必须使用闭包来实现即时绑定(IIFE)。

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单体模式的全面解析,希望能为读者提供帮助。如有任何疑问,欢迎留言交流,小编将及时回复。感谢大家对本站的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章