【问题标题】:Check the existence of variable in the global namespace without alternate name检查全局命名空间中是否存在没有备用名称的变量
【发布时间】:2013-11-04 17:32:11
【问题描述】:

作为 Javascript 设计模式的新手,我遇到了模块模式,但我没有得到与命名空间有关的东西。

在the namespacing part of Addy Osmani's online book about JS Design Patterns 中,Addy 解释了这 5 种检查变量/命名空间存在的方法:

// This doesn't check for existence of "myApplication" in
// the global namespace. Bad practice as we can easily
// clobber an existing variable/namespace with the same name
var myApplication = {};

// The following options *do* check for variable/namespace existence. 
// If already defined, we use that instance, otherwise we assign a new 
// object literal to myApplication.
// 
// Option 1: var myApplication = myApplication || {};
// Option 2  if( !MyApplication ){ MyApplication = {} };
// Option 3: window.myApplication || ( window.myApplication = {} );
// Option 4: var myApplication = $.fn.myApplication = function() {};
// Option 5: var myApplication = myApplication === undefined ? {} : myApplication;

我真正不明白的是它是如何解决命名问题的。

假设在我的代码尝试使用 myApplication 之前设置了 myApplication。例如,使用选项 1(或实际上所有选项),如果 myApplication 已在使用中,似乎并没有改变任何东西,但只会覆盖 myApplication 以前的值:

// Higher in some script, where I don't know about it
var myApplication = 'whatever string or object used by the script';

// A bit of code later, where I come with my little Module Pattern
var myApplication = myApplication || {}; // Using Option 1

myApplication = (function($) {
   var myAppVariable = 'blabla';

   var myAppFunction = function() {
       // Doing a few things here
   };

   return myAppFunction;
}) (jQuery);

// Using the module
myApplication.myAppFunction();

对我来说,这很令人困惑,因为我不明白它如何阻止我踩到别人的脚趾。

【问题讨论】:

  • 是的,该模式不会保留原始 myApplication
  • 但是您没有遵循模式:您执行条件分配,然后立即执行分配而不进行检查。赋值正是这样做的;如果你不做任何事情来避免践踏你的价值,那么你就不会做任何事情来避免践踏你的价值。具体问题是什么?
  • @dave-newton 我想具体的问题是如何避免使用 myApplication 如果之前已经使用过(我认为这些选项应该这样做)?有没有一种简短的方法可以提供替代名称或其他名称?
  • 那些选项 do 做到了。然后你转身并通过直接分配来覆盖它。我不明白这是什么混乱。
  • @dave-newton 好的,那么我想困惑是关于如何“不转身并通过直接分配来覆盖它”,如何正确地完成分配。

标签: javascript design-patterns namespaces module-pattern


【解决方案1】:

当您在 javascript 中加载模块时,您可能(取决于我猜的代码)将不得不覆盖模块名称空间中已经存在的任何变量。在加载之前保留模块名称的流行模式是noConflict() 模式。这种模式背后的想法是您将命名空间的原始值保存在一个变量中,如果调用noConflict,则将您的命名空间替换为原始值并返回您的库。模式可以或多或少优雅地写成这样:

myModule = "some stuff ya";

(function(namespace, undefined) {
    var _module = "myModule";
    var __originalModule = namespace[_module];//holds the original value in case you wish to restore it

    /****** Code your module here following whichever module pattern you wish to follow ****/
    var module = {
        log: function() {
            if(console.log) {
                console.log(arguments);
            }
        }
    }
    /****** End of your module ****/

    //calling this method will remove your module from the namespace and replace it with whatever
    // originally held your module name.
    //This function returns your module
    module.noConflict = function() {
        namespace[_module] = __originalModule;
        return module;
    }

    namespace[_module] = module; //add your module to the namespace

})(window);

console.log(window.myModule); // => {log: function...}
var myMod = window.myModule.noConflict();
console.log(window.myModule); // => "some stuff ya"

【讨论】:

    猜你喜欢
    • 2015-08-17
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 2011-03-25
    • 2019-06-26
    • 1970-01-01
    • 2011-08-31
    • 2017-01-04
    相关资源
    最近更新 更多