2

我的目标:命名我的 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();
        }

    }

}

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

4

3 回答 3

4

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

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: { ... } 
  };
})();

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

于 2012-07-06T19:10:31.630 回答
1

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

MyPageMethods.ModalPopupOverrides.modalPopupStack

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

var modalPopupStack = MyPageMethods.ModalPopupOverrides.modalPopupStack;

请注意,该值在全局范围内仍然可见(与@JaredPar 的答案不同),但它只是在现有全局对象上的捎带。

于 2012-07-06T19:14:26.220 回答
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 = [];

It's shorter, cleaner, and really more explicit.

于 2012-07-06T19:18:47.180 回答