如何组合匿名函数?

时间:2013-10-20 20:36:11

标签: javascript design-patterns plugins

从SO和其他地方看,看起来没有办法扩展匿名功能。 ...但是,请参阅我谷歌在他们的谷歌分析(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
})();

有没有办法或解决方法可以在不暴露我的所有方法的情况下实现这一目标?

2 个答案:

答案 0 :(得分:2)

使用revealing module pattern和单个全局命名空间对象的组合。像这样:

//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 
    };
}());

答案 1 :(得分: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 || {});

稍后您创建一个Master / Combo

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()   执行。