使用standalones扩展脚本,同时保持全球空间清洁

时间:2013-11-24 22:28:16

标签: javascript design-patterns

我正在努力解决这个问题。

我有一些脚本:

  1. 一个简单的绘图仪,用于在画布上绘制图形。
  2. 通过XMLHttpRequest记录,发布和获取日志。
  3. 一个cookie处理程序,一般cookie处理程序。
  4. 用于保存和加载图像的IndexedDB脚本。
  5. 它们都可以工作,可以独立使用。是自包含的,并保存在单独的文件中。

    他们的布局如下:

    var Plotter = (function () {
        'use strict';
        function Plotter (opt) {
    
        }
    
        Plotter.prototype.fun1 () {}
        Plotter.prototype.fun2 () {}
    
        return Plotter;
    })();
    

    现在我有一个脚本,我将这些组合在一起,此外还有许多其他的东西。

    var my_app = function () {
        this.init = function () {
    
        }
        this.fun2 = function () {
            this.plotter = new Plotter(opt);
            ...
        }
        this.fun3 = function () { }
    };
    

    我希望以这样的方式设计它,除了my_app之外我不需要污染全球环境。

    我不希望MyPlotterMyLogger等作为全局变量,但是:

    my_app = function () {
        var Plot = Plotter;
        ...
        this.fun2 = function () {
            this.plotter = new Plot(opt);
        }
    }
    

    有没有办法解决这个问题?

    本质上是用其他脚本扩展my_app,同时保持全局空间不受污染。

    当一个人有两个或三个额外的全局变量时,也许没关系,但是当它变得比10-20变得更多时,它就没有了......我甚至不喜欢有两个。会留在那一个。

    我显然必须改变一些事情,但主要的是继续保持文件分开,以便我可以使用,例如Logger在一个单独的项目中。  使用服务器端代码很容易解决为my_app和单独的脚本生成组合空间,但更愿意不这样做。


    编辑:

    在查看T.J. Crowdersolution后,我想我现在就去找一个变体。相信也许我会使用各种各样的库,如:

    if ('Library' in global) {
        global.Library.Plotter = Plotter;
    } else {
        global.Plotter = Plotter;
    }
    

    然后在my_app说:

    this.Plott = new Library.Plotter();
    

    它仍然留给我两个全局变量,这是我想要的一个,(我可能在这里很愚蠢),但是它不会与一个名字耦合。一个更好的解决方案可能就是总是说:

    if ('Library' in global) {
        global.Library.Plotter = Plotter;
    } else {
        global.Library = {Plotter:Plotter};
    }
    

    这种方式在脚本之间是一致的。 (哎呀,现在看起来很简单。)

    我知道这不是我的要求,但毕竟这可能是一种更好的方法。这是一个设计问题,如果我做得对,我很不舒服。

1 个答案:

答案 0 :(得分:2)

你可以这样做:

(function (global) {
    'use strict';
    function Plotter (opt) {

    }

    Plotter.prototype.fun1 () {}
    Plotter.prototype.fun2 () {}

    if ('my_app' in global) {
        global.my_app.Plotter = Plotter;
    }
    else {
        global.Plotter = Plotter;
    }
})(this);

如果要将事物组合到my_app中,请从全局命名空间中将my_app定义为对象的脚本开始:

var my_app = {};

// or
this.my_app = {};

如果您想单独使用Plotter,请不要,并且会创建Plotter全局。