JavaScript,如何在使用单例时保持适当的封装

JavaScript, how to keep proper encapsulation in place while using a singleton?

本文关键字:封装 单例时 JavaScript      更新时间:2023-09-26

我想开始更好地构建我的JavaScript,这样我就不会污染全局命名空间,并练习更好的封装和继承,正如我在本次代码审查中所描述的那样:https://codereview.stackexchange.com/q/64556/42628

所以,举个例子(这里是一个小提琴)。。。

window.myPage = {
    init:function(){
        //local "Private" declarations
        var gridHandle1 = new myPage.MyGrid();
        gridHandle1.loadGridData();
    },
    MyGrid: function(){
        /* local "Private" declarations */
        var dataLoadTimes = 0;
        var gridDrawn = true;
        $('#debug').append('grid is drawn<br>');
        //This needs to be a public method because
        //other functions need to reload the grid
        //at various times. So I will use "this."
        //instead of "var".  "var" would make it a
        //private method.
        this.loadGridData = function() {
            dataLoadTimes = dataLoadTimes+1;
            $('#debug').append('grid data has been loaded '+dataLoadTimes+' times<br>');
        };
        this.loadGridData();
    }
};
myPage.init();
// console.log(gridHandle1); // <--- fails, GOOD, it's not in the global namespace
// console.log(gridDrawn); // <--- fails, GOOD, it's not in the global namespace

我理解这里发生的一切,我喜欢它,因为"loadGridData"只属于"MyGrid",它没有任何意义,因为它自己的功能不属于"MyGrid",这会破坏封装。但这样做需要这条线。。。

var gridHandle1 = new myPage.MyGrid();

这很酷,它允许我创建许多这样的网格。。。

var gridHandle1 = new myPage.MyGrid();
var gridHandle2 = new myPage.MyGrid();
var gridHandle3 = new myPage.MyGrid();

但在这种情况下,我不需要太多网格。我只需要一个。所以我的问题是,我该如何调整这段代码,使所有东西都能正常工作,但作为一个单例执行,而不是使用"类"的方式,并使用构造函数实例化对象?

有几种方法可以实现这一点,并最终取决于偏好。

就我个人而言,我的代码是这样的:(没有jquery——我不使用它)

var myPage = {
  ua: {}
}
$(function() {
   myPage.mainLayout = new dhtmlXLayoutObject(document.body, "2U");
   myPage.mainTabBar = myPage.mainLayout.cells("b").attachTabbar();
   myPage.initTab(myPage.mainTabBar);
});

myPage.initTab=function(tb){  
   tb.xyz();
}: 

myPage.ua.load=function(id){
    myPage.ua.innerLayout = myPage.mainTabBar.tabs(id).attachLayout("1C");
    myPage.ua.grid        = myPage.ua.innerLayout.cells("a").attachGrid();
}
myPage.ua.search = function() {
    myPage.ua.grid.clearAndLoad([theUrl], "json");
};

有时我定义ua,有时我将所有内容都绑定到myPgae