2012-07-06 81 views
2

我的目标:命名空间我的JavaScript保持全局名称空间干净。在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(); 
     } 

    } 

} 

我敢肯定有一个简单的解决这个,但我不知道它是什么。

+0

让名称空间的一部分可以包含可由所有方法命名空间访问的变量。 – 2012-07-06 19:10:42

回答

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

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

+0

+1 - 如果你真的想要限制对价值的访问,那么这就是要走的路。 – 2012-07-06 19:17:26

1

可以使用引用这两种方法该属性:

MyPageMethods.ModalPopupOverrides.modalPopupStack 

这可以是一个有点麻烦,所以你可能会想它的别名每个方法里面,像这样:

var modalPopupStack = MyPageMethods.ModalPopupOverrides.modalPopupStack; 

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

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 = []; 

它更短,更干净,而且更加明确。