0

从 SO 和其他地方看,似乎没有一种方法可以扩展匿名函数。 ...但是,看到我 Google 在他们的 google 分析 (analytics.js) 跟踪脚本中做了类似的事情,我不确定如何复制相同的内容。

基本上我有一堆方法包装在一个匿名函数中。我不希望它们泄漏到全局命名空间中。

但是...我需要能够让用户有选择地加载“扩展”原始脚本的插件(位于单独的 javascript 文件中)。我这样做是为了使原始脚本尽可能小。我看不到一种方法可以将我的脚本分解为多个文件,然后根据用户指定的选项即时连接在一起,而不暴露所有方法以便他们可以通信。然而,这也将使它们可供其他人使用,因此他们可能不会按预期使用脚本。

总而言之,我想要:

(function() {
// Main.js
....
Based on user input combine with plugin1.js so i can call his methods and he can call mine
})();

(function() {
// Plugin1.js
// More methods
})();

是否有任何方法或解决方法可以在不暴露我所有方法的情况下完成此操作?

4

2 回答 2

2

使用显示模块模式和单个全局命名空间对象的组合。像这样:

//main.js
if (window.MY_APP === undefined) {
    window.MY_APP = {};
}

window.MY_APP.main = (function () {
    //Your code
    var registerPlugin = function() { ... },
        unregisterPlugin = function () { ... };


    return { //Here you expose the functions you want to be public
        registerPlugin: registerPlugin,
        unregisterPlug: unregisterPlugin
    };
}());

//Plugin.js
if (window.MY_APP === undefined) {
    window.MY_APP = {};
}

window.MY_APP.myPlugin = (function() {
    //Plugin code


    return {
       //public methods of plugin 
    };
}());
于 2013-10-20T20:53:42.937 回答
1

可能的解决方案

这是我刚刚想出的一个有趣的解决方案。这几乎是不言自明的,我评论了代码。希望它能达到目的。

var p1 = (function (self) {
    // private stuff - 
    var hiddenInfo1 = "PlugIn 1's Secret Info";
    var hiddenMethod1 = function () {
        alert(hiddenInfo1);
    }
    // public stuff
    self.exposedMethod = function () {
        alert("PlugIn 1's Public Info");
    }
    self.getPrivateAccess = function () {
        return {
            seal: function () { delete self.getPrivateAccess },
            // - list of shared private stuffs
            hiddenMethod1: hiddenMethod1,
        }
    }
    return self;
})(p1 || {});

稍后您创建一个主/组合

var master = (function (self, p1) {
    // get p1's private stuffs.
    var p1sPrivs = p1.getPrivateAccess();
    // now seal p1 so that no one else can request it.
    p1sPrivs.seal();
    // just to make sure, uncomment this line and get a runtime error. ;)
    // p1.getPrivateAccess();

    // let's define a function for the masses....
    self.shoutAll = function () {
        p1.exposedMethod();
        p1sPrivs.hiddenMethod1();
        alert("Master's Public Method");
    }
    return self;
})(master || {}, p1);

// now use it.
master.shoutAll();

这个想法来自位于http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html的这篇很棒的文章。尤其是进入称为Cross-File Private State.

将模块拆分为多个文件的一个严重限制是每个文件都维护自己的私有状态,并且无法访问其他文件的私有状态。这可以修复。这是一个松散增强模块的示例,它将在所有增强中保持私有状态:

var MODULE = (function (my) {
    var _private = my._private = my._private || {},
        _seal = my._seal = my._seal || function () {
            delete my._private;
            delete my._seal;
            delete my._unseal;
        },
        _unseal = my._unseal = my._unseal || function () {
            my._private = _private;
            my._seal = _seal;
            my._unseal = _unseal;
        };

    // permanent access to _private, _seal, and _unseal

    return my;
}(MODULE || {}));

任何文件都可以在其局部变量 _private 上设置属性,并且它将立即可供其他文件使用。一旦这个模块完全加载,应用程序应该调用 MODULE._seal(),这将阻止外部访问内部 _private。如果要再次扩充此模块,则在应用程序的生命周期中,任何文件中的内部方法之一都可以在加载新文件之前调用 _unseal() ,并在执行后再次调用 _seal() 。

于 2013-10-20T20:57:29.087 回答