65.9K
CodeProject 正在变化。 阅读更多。
Home

JavaScript 中的封装

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (56投票s)

2010年9月13日

CPOL

3分钟阅读

viewsIcon

145430

downloadIcon

582

本文通过一个示例演示如何在 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 如何帮助动态更改页面的主题。

**编程是诗歌**

© . All rights reserved.