JavaScript 中的封装
本文通过一个示例演示如何在 JavaScript 中创建公共和私有成员。
引言
封装 是面向对象编程的主要概念之一。它允许对象将私有和公共成员组合在一个名称下。所有面向对象的编程语言都支持这一点。由于 JavaScript 也是一种面向对象的编程语言,因此它也支持它。
在本文中,我们将通过创建一个名为 CssManager
的简单对象来了解如何在 JavaScript 中实现封装,该对象有助于动态添加、删除或交换样式表。
计划
- 创建一个名为
Managers
的命名空间,用于包装我们的对象。 - 创建一个名为
CssManager
的单例对象。 - 向对象添加公共方法,用于添加、删除和交换样式表。
- 创建私有成员。
代码
创建一个名为 Managers
的命名空间,用于包装我们的对象
在 JavaScript 中,创建一个命名空间就像创建一个对象字面量一样简单。
var Managers = {}; //namespace
非常简单,对吧?
现在,您可以将所有与 Managers
相关的类和对象包装在一个命名空间中。
创建一个名为 CssManager
的单例对象
Managers.CssManager = { //singleton
}
花括号对之间的代码构成对象的一部分。
向对象添加公共方法,用于添加、删除和交换样式表
在 JavaScript 中,对象的作用很像关联数组,即键值对数组。键是属性或方法。
创建 addStyleSheet
方法,该方法接受两个参数:样式表元素 ID 和引用 URL。
Managers.CssManager = {
addStyleSheet: function(id, url){ //id - link's id, url - link's href
}
}
在 addStyleSheet()
中,我们将执行以下操作:动态创建一个链接元素,设置其属性,并将其附加到 head 部分。
Managers.CssManager = {
addStyleSheet: function(id, url){
var newStyleSheet = document.createElement("link");
newStyleSheet.setAttribute("rel", "stylesheet");
newStyleSheet.setAttribute("type", "text/css");
newStyleSheet.setAttribute("id", id);
newStyleSheet.setAttribute("href", url);
document.getElementsByTagName("head")[0].appendChild(newStyleSheet);
}
}
添加其他两个方法。
Managers.CssManager = {
addStyleSheet: function(id, url){
var newStyleSheet = document.createElement("link");
newStyleSheet.setAttribute("rel", "stylesheet");
newStyleSheet.setAttribute("type", "text/css");
newStyleSheet.setAttribute("id", id);
newStyleSheet.setAttribute("href", url);
document.getElementsByTagName("head")[0].appendChild(newStyleSheet);
},
removeStyleSheet: function(id){
var currentStyleSheet = document.getElementById(id);
if(currentStyleSheet){
currentStyleSheet.parentNode.removeChild(currentStyleSheet);
}
},
swapStyleSheet: function(id, url){
this.removeStyleSheet(id);
this.addStyleSheet(id, url);
}
}
在 removeStyleSheet
中,我们查询特定的样式表元素(链接)并将其从 DOM 中完全删除。 而在 swapStyleSheet
中,我们调用其他两个方法来用新的样式表替换现有的样式表。
创建私有成员
到目前为止,创建的所有方法都是公共的。为了本文的目的,我想添加两个私有成员。第一个是具有对 document
对象引用的变量。
var doc = document;
第二个是一种一次性为链接元素设置多个属性,而不是多次调用 setAttribute()
的方法。
var setAttributes = function(attributes){
}
与其他语言不同,我们无法在 JavaScript 中轻松地将成员标记为公共或私有。要创建私有成员,我们必须使用闭包。 闭包有助于创建私有空间。 我们不会在此处讨论什么是闭包,但让我们看看它们如何帮助创建私有成员。
让我们修改我们的 CssManager
以应用闭包
Managers.CssManager = (function(){
/*
private space
*/
return{
//Public members
addStyleSheet: function(id, url){
var newStyleSheet = doc.createElement("link");
setAttributes(newStyleSheet, {
rel : "stylesheet",
type : "text/css",
id : id,
href: url
});
doc.getElementsByTagName("head")[0].appendChild(newStyleSheet);
},
removeStyleSheet: function(id){
var currentStyleSheet = doc.getElementById(id);
if(currentStyleSheet){
currentStyleSheet.parentNode.removeChild(currentStyleSheet);
}
},
swapStyleSheet: function(id, url){
this.removeStyleSheet(id);
this.addStyleSheet(id, url);
}
}
})();
我们所做的是创建了一个闭包,它看起来像一个自执行的匿名函数,该函数返回我们之前添加的公共方法。末尾的括号对使代码自动执行。 return
语句返回的所有成员都是公共的,而之前的成员都是私有的。
(function(){
//Private members
return{
//Public members
}
}();
在私有空间中添加我们的两个新成员
Managers.CssManager = (function(){
//Private members
var doc = document;
var setAttributes = function(element, attributes){
for(attribute in attributes){
element[attribute] = attributes[attribute];
}
}
return{
//Public members
addStyleSheet: function(id, url){
var newStyleSheet = doc.createElement("link");
setAttributes(newStyleSheet, {
rel : "stylesheet",
type : "text/css",
id : id,
href: url
});
doc.getElementsByTagName("head")[0].appendChild(newStyleSheet);
},
removeStyleSheet: function(id){
var currentStyleSheet = doc.getElementById(id);
if(currentStyleSheet){
currentStyleSheet.parentNode.removeChild(currentStyleSheet);
}
},
swapStyleSheet: function(id, url){
this.removeStyleSheet(id);
this.addStyleSheet(id, url);
}
}
})();
如何使用
我们的 CssManager
已准备就绪! 如果你想动态地向一个页面添加一个样式表,调用 addStyleSheet
方法,传递一个唯一的 ID 和外部 CSS 文件的 HREF,如下所示
Managers.CssManager.addStyleSheet("myStyleSheet", "Default.css");
同样地,你甚至可以移除它或者用一个新的样式表替换它
Managers.CssManager.removeStyleSheet("myStyleSheet");
Managers.CssManager.swapStyleSheet("myStyleSheet", "Advanced.css");
就这样!我们完成了!!感谢阅读。 如果你觉得这篇文章对你有帮助,别忘了投票。 请查看附带的示例代码,该代码展示了 CssManager
如何帮助动态更改页面的主题。
**编程是诗歌**