作为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();
对我而言,这是非常令人困惑的,因为我看不出它如何阻止我踩到别人的脚趾。
答案 0 :(得分:0)
当您在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"