在JavaScript命名空间中共享变量

时间:2012-07-06 19:07:32

标签: javascript javascript-namespaces

我的目标:命名我的javascript以保持全局命名空间清洁。

我的问题:如何在JavaScript命名空间中的方法之间共享变量?

在我的示例中,我正在扩展并覆盖ASP.net ModalPopupExtender的行为。我想知道如何将modalPopupStack变量与ModalPopupShowOverrideModalPopupHideOverride分享,而不是将其全局化。

相关代码:

$(function () {
    if (Sys.Extended != undefined && Sys.Extended.UI != undefined && Sys.Extended.UI.ModalPopupBehavior != undefined) {
        MyPageMethods.ModalPopupShowOriginal = Sys.Extended.UI.ModalPopupBehavior.prototype.show;
        MyPageMethods.ModalPopupHideOriginal = Sys.Extended.UI.ModalPopupBehavior.prototype.hide;
        Sys.Extended.UI.ModalPopupBehavior.prototype.show = MyPageMethods.ModalPopupOverrides.ModalPopupShowOverride;
        Sys.Extended.UI.ModalPopupBehavior.prototype.hide = MyPageMethods.ModalPopupOverrides.ModalPopupHideOverride;
    }
});

var MyPageMethods = {

    ModalPopupShowOriginal: function () { },

    ModalPopupHideOriginal: function () { },

    ModalPopupOverrides: {

        modalPopupStack: new Array(),

        ModalPopupShowOverride: function () {

            var extender = this;
            var topElement;

            MyPageMethods.ModalPopupShowOriginal.apply(this, arguments);

            for (var x = 0; x < modalPopupStack.length; x++) {

                if ($(modalPopupStack[x].background).css("z-index") > $(extender._element).css('z-index') || $(modalPopupStack[x].popup).css("z-index") > $(extender._element).css('z-index')) {

                    if ($(modalPopupStack[x].background).css("z-index") > $(extender._element).css('z-index')) {
                        topElement = $(modalPopupStack[x].background).css("z-index");
                    }
                    else if ($(modalPopupStack[x].popup).css("z-index") > $(extender._element).css('z-index')) {
                        topElement = $(modalPopupStack[x].popup).css("z-index");
                    }

                }

            }

            if (topElement != undefined) {
                $(extender._backgroundElement).css('z-index', topElement);
            }

            modalPopupStack.push({ 'id': extender._id, 'background': extender._backgroundElement, 'popup': extender._element });

        },

        ModalPopupHideOverride: function () {
            var extender;
            MyPageMethods.ModalPopupHideOriginal.apply(this, arguments);
            extender = modalPopupStack.shift();
        }

    }

}

我确信这有一个简单的解决方案,但我不确定它是什么。

3 个答案:

答案 0 :(得分:3)

听起来您希望变量在命名空间中可见但不在其外部。如果是,请尝试以下解决方案。

var MyPageMethods = (function() { 
  // This variable is local to the namespace.  It can't be accessed from 
  // the caller
  var modalPopupStack = new Array();

  // These values are available to the callers as members of MyPageMethods
  return { 
    ModalPopupShowOriginal: function () { },

    ModalPopupHideOriginal: function () { },

    ModalPopupOverrides: { ... } 
  };
})();

此模式使用函数为命名空间的局部变量建立私有函数范围。然后它返回一个新对象,其中包含可在命名空间外部访问的成员。这些定义发生在函数内部,因此它们可以访问命名空间私有数据。

答案 1 :(得分:1)

您可以使用以下方法在两种方法中引用该属性:

MyPageMethods.ModalPopupOverrides.modalPopupStack

这可能有点麻烦,因此您可能希望在每个方法中对其进行别名,如下所示:

var modalPopupStack = MyPageMethods.ModalPopupOverrides.modalPopupStack;

请注意,该值在全局范围内仍然可见(与@ JaredPar的答案不同),但它仅仅依赖于现有的全局对象。

答案 2 :(得分:0)

如果您愿意,可将其作为命名空间的一部分。或者为了更加隐私,制作一个包含它的本地闭包并公开你想要的功能:

var MyPageMethods = {
    ModalPopupShowOriginal: function () { },
    ModalPopupHideOriginal: function () { },
    ModalPopupOverrides: (function() {
        var modalPopupStack = new Array();
        var show = function () {
            // show implementation using modalPopupStack
        };
        var hide = function () {
            // hide implementation using modalPopupStack
        };
        return {
            ModalPopupShowOverride: show,
            ModalPopupHideOverride: hide
        }
    }())
};

顺便说一下,这些天使用new Array()的情况非常少见。这通常是首选:

        var modalPopupStack = [];

它更短,更清洁,更真实。