例如:
Dashboard.Ajax.Post()
Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent();
我还想将它们放在单独的文件中:
- Ajax.js
- RetrieveContent.js
然而,我尝试使用这种方法,但它不起作用,因为相同的变量名被用于两个不同的命名空间。是否有其他替代方法?
谢谢。
Dashboard.Ajax.Post()
Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent();
我还想将它们放在单独的文件中:
然而,我尝试使用这种方法,但它不起作用,因为相同的变量名被用于两个不同的命名空间。是否有其他替代方法?
谢谢。
您只需要确保如果命名空间对象已经被创建,不要重复定义。可以像这样实现:
(function() {
// private vars can go in here
Dashboard = Dashboard || {};
Dashboard.Ajax = {
Post: function() {
...
}
};
})();
而RetrieveContent
文件的定义类似。
Dashboard = Dashboard || {};
(如果这是我的命名空间)?其次,我是否必须在每个变量前加上Dashboard.x而不是x,还是因为所有内容都在同一命名空间中,所以这不是必要的? - Michel(function(window){
var dashboard = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
window.Dashboard = dashboard;
})(window);
dashboard.ajax.js
var dashboard = (function (my) {
var _private = my._private = my._private || {},
_seal = my._seal = my._seal || function () {
delete my._private;
delete my._seal;
delete my._unseal;
},
_unseal = my._unseal = my._unseal || function () {
my._private = _private;
my._seal = _seal;
my._unseal = _unseal;
};
// permanent access to _private, _seal, and _unseal
my.ajax = function(){
// ...
}
return my;
}(dashboard || {}));
dashboard.retrieveContent.js
var dashboard = (function (my) {
var _private = my._private = my._private || {},
_seal = my._seal = my._seal || function () {
delete my._private;
delete my._seal;
delete my._unseal;
},
_unseal = my._unseal = my._unseal || function () {
my._private = _private;
my._seal = _seal;
my._unseal = _unseal;
};
// permanent access to _private, _seal, and _unseal
my.retrieveContent = function(){
// ...
}
return my;
}(dashboard || {}));
var NS = NS || {};
以确保NS对象存在且不被覆盖。// NS is a global variable for a namespace for the app's code
var NS = NS || {};
NS.Obj = (function() {
// Private vars and methods always available to returned object via closure
var foo; // ...
// Methods in here are public
return {
method: function() {
}
};
}());
如果您想使用或检查已经提供此类功能的预制(即经过测试的)解决方案,那么已经有几个库可以提供这样的功能。
最简单和最没有错误的方法是使用 jQuery.extend
,并将 deep
参数设置为 true。我之所以说它没有错误,不是因为我认为 jQuery.extend
比其他库更少出错,而是因为它提供了一个明确的选项,可以从发送方深度复制属性到接收方,而大多数其他库则明确没有提供此功能。这将防止许多难以诊断的错误在程序后期出现,因为您使用了浅层复制的 extend
,现在函数在您不希望它们执行的上下文中执行。(但是,如果您在设计方法时注意到将扩展基本库的方式,这应该不会成为问题。)
我强烈推荐您使用这种技术:
https://github.com/mckoss/namespace
namespace.lookup('com.mydomain.mymodule').define(function (ns) {
var external = namespace.lookup('com.domain.external-module');
function myFunction() {
...
}
...
ns.extend({
'myFunction': myFunction,
...
});
});
<html>
<head>
<title>javascript namespacing</title>
<script src="dashboard.js" type="text/javascript"></script>
<script src="ajax.js" type="text/javascript"></script>
<script src="retrieve_content.js" type="text/javascript"></script>
<script type="text/javascript">
alert(Dashboard.Ajax.Post());
alert(Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent());
Dashboard.RetrieveContent.Settings.Timeout = 1500;
alert(Dashboard.RetrieveContent.Settings.Timeout);
</script>
</head>
<body>
whatever...
</body>
</html>
Dashboard.js:
(function(window, undefined){
var dashboard = {};
window.Dashboard = dashboard;
})(window);
Ajax.js:
(function(){
var ajax = {};
ajax.Post = function() { return "Posted!" };
window.Dashboard.Ajax = ajax
})();
Retrieve_Content.js:
(function(){
var retrieveContent = {};
retrieveContent.RefreshSalespersonPerformanceContent = function() {
return "content retrieved"
};
var _contentType;
var _timeout;
retrieveContent.Settings = {
"ContentType": function(contentType) { _contentType = contentType; },
"ContentType": function() { return _contentType; },
"Timeout": function(timeout) { _timeout = timeout; },
"Timeout": function() { return _timeout; }
};
window.Dashboard.RetrieveContent = retrieveContent;
})();
Dashboard.js 是其下所有命名空间的起点。其余部分在各自的文件中定义。在 Retrieve_Content.js 中,我添加了一些额外的属性在 Settings
下面,以便在需要时提供如何执行的想法。
retrieve_content.js
会在Dashboard.js
之后被加载和解析。如果任何依赖库在Dashboard.js
加载之前被加载,则分配将失败。 - Sean VieiraDashboard.js
会首先被加载和解析,但这并不是保证的。如果需要,可以在分配之前检查 Dashboard
对象并进行创建,但这将需要在 retrieve_content.js
和 ajax.js
中重复一些代码。OP 的单独文件要求导致我做出了上述决定。 - ironsamfunction ns(nsstr) {
var t = nsstr.split('.');
var obj = window[t[0]] = window[t[0]] || {};
for (var i = 1; i < t.length; i++) {
obj[t[i]] = obj[t[i]] || {};
obj = obj[t[i]];
}
}
ns('mynamespace.isawesome.andgreat.andstuff');
mynamespace.isawesome.andgreat.andstuff = 3;
console.log(mynamespace.isawesome.andgreat.andstuff);
我相信模块模式可能非常适合你。这里有一篇关于不同模块模式的好文章。
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
实现:
namespace = function(packageName)
{
// Local variables.
var layers, layer, currentLayer, i;
// Split the given string into an array.
// Each element represents a namespace layer.
layers = packageName.split('.');
// If the top layer does not exist in the global namespace.
if (eval("typeof " + layers[0]) === 'undefined')
{
// Define the top layer in the global namesapce.
eval(layers[0] + " = {};");
}
// Assign the top layer to 'currentLayer'.
eval("currentLayer = " + layers[0] + ";");
for (i = 1; i < layers.length; ++i)
{
// A layer name.
layer = layers[i];
// If the layer does not exist under the current layer.
if (!(layer in currentLayer))
{
// Add the layer under the current layer.
currentLayer[layer] = {};
}
// Down to the next layer.
currentLayer = currentLayer[layer];
}
// Return the hash object that represents the last layer.
return currentLayer;
};
结果:
namespace('Dashboard.Ajax').Post = function() {
......
};
namespace('Dashboard.RetrieveContent').RefreshSalespersonPerformanceContent = function() {
......
};
概要: