包含可以相互访问的对象的JavaScript函数

时间:2014-12-02 15:48:10

标签: javascript

我最初的代码如下所示,我在全局命名空间中没有任何内容,我能够从obj1调用obj2中的函数,反之亦然。一切都很好。

(function() {
    var obj1 = {
        obj1_f1 : function() {
        },
        obj1_f2 : function() {
            obj2.obj2_f1();
        }
    };
    var obj2 = {
        obj2_f1 : function() {
            obj1.obj1_f1();
        },
        obj2_f2 : function() {
        }
    };
    $(document).ready(function () {
        obj1_f1();
    });
})();

但是现在我需要从全局上下文中调用obj1对象中的函数,所以我必须引入一个全局对象:

var com_mycompany_make_sure_unique = new function() {
    // use 'this.' so that obj1 is not in the global namespace
    this.obj1 = {
        obj1_f1 : function() {
        },
        obj1_f2 : function() {
            com_mycompany_make_sure_unique.obj2.obj2_f2();
        }
    };
    this.obj2 = {
        obj2_f1 : function() {
            com_mycompany_make_sure_unique.obj1.obj1_f1();
        },
        obj2_f2 : function() {
        }
    };

    $(document).ready(function () {
        com_mycompany_make_sure_unique.obj1.obj1_f1();
    });
};

但我对此并不满意 - 在调用obj1和obj2中的函数时,我必须使用我的全局对象名称添加所有函数调用。我想我错过了一招。

感谢您的帮助,

1 个答案:

答案 0 :(得分:2)

你可以这样做(见评论):

var com_mycompany_make_sure_unique = function() {
    // Continue using variables as you were before
    var obj1 = {
        obj1_f1 : function() {
        },
        obj1_f2 : function() {
            obj2.obj2_f2();
        }
    };
    var obj2 = {
        obj2_f1 : function() {
            obj1.obj1_f1();
        },
        obj2_f2 : function() {
        }
    };

    $(document).ready(function () {
        obj1.obj1_f1();
    });

    // Return an object that can be used via the `com_mycompany_make_sure_unique` variable
    return {
        obj1: obj1,
        obj2: obj2
    };
}();

这有时被称为“揭示模块模式”,因为外部匿名作用域功能内部的所有内容都是私有的,然后通过将它们放在您返回的对象上来“显示”要显示的部分。如果您只需要公开obj1,而不是obj2,那么您可以这样做:

return {
    obj1: obj1
};

我的问题是为什么你需要从全局上下文中调用函数吗?使用现代事件处理和像RequireJS这样的异步模块定义加载器,你应该真正需要的唯一全局(ugh)是AMD函数。


附注:我已将var ... = new function() { ... };替换为var ... = function() { ... }();此处无需使用new,这样做可能会让人感到困惑(并为结果对象提供额外的原型)不需要)。但如果您愿意,可以使用原始表格,只需将结尾更改为

即可
this.obj1 = obj1;
this.obj2 = obj2;

...而不是返回一个对象。