我的目标:命名我的javascript以保持全局命名空间清洁。
我的问题:如何在JavaScript命名空间中的方法之间共享变量?
在我的示例中,我正在扩展并覆盖ASP.net ModalPopupExtender的行为。我想知道如何将modalPopupStack
变量与ModalPopupShowOverride
和ModalPopupHideOverride
分享,而不是将其全局化。
相关代码:
$(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();
}
}
}
我确信这有一个简单的解决方案,但我不确定它是什么。
答案 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 = [];
它更短,更清洁,更真实。