Reputation: 7861
My Goal: To namespace my javascript to keep the global namespace clean.
My question: how do I share variables between methods in my JavaScript namespace?
In my example I am extending and overwriting the behaviour of the ASP.net ModalPopupExtender. I want to know how I can share the modalPopupStack
variable with ModalPopupShowOverride
and ModalPopupHideOverride
without making it global.
Relevant code:
$(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();
}
}
}
I'm sure there is a simple solution to this, but I'm not sure what it is.
Upvotes: 2
Views: 757
Reputation: 50787
Make it part of the namespace, if you like. Or for more privacy, make a local closure which incorporates it and exposes the functions you want:
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
}
}())
};
By the way, it's pretty rare to use new Array()
these days. This is usually preferred:
var modalPopupStack = [];
It's shorter, cleaner, and really more explicit.
Upvotes: 0
Reputation: 60414
You can reference that property in both methods using:
MyPageMethods.ModalPopupOverrides.modalPopupStack
That can be a little bit cumbersome, so you'd likely want to alias it inside each method, like this:
var modalPopupStack = MyPageMethods.ModalPopupOverrides.modalPopupStack;
Note that the value is still visible in the global scope (unlike in @JaredPar's answer), but its merely piggy-backing on an existing global object.
Upvotes: 1
Reputation: 754665
It sounds like you want the variables to be visible within your namespace but not outside of it. If so then try the following solution.
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: { ... }
};
})();
This pattern uses a function to establish a private function scope for local variables of the namespace. It then returns a new object which contains the members accessible outside the namespace. Those definitions occur inside the function hence they can access the namespace private data.
Upvotes: 4