/**
* My JavaScript application
*
* @module myapp
*/
/** @namespace Namespace for MYAPP classes and functions. */
var MYAPP = MYAPP || {};
/**
* A maths utility
* @namespace MYAPP
* @class math_stuff
*/
MYAPP.math_stuff = {
/**
* Sums two numbers
*
* @method sum
* @param {Number} a First number
* @param {Number} b Second number
* @return {Number} Sum of the inputs
*/
sum: function (a, b) {
return a + b;
},
/**
* Multiplies two numbers
*
* @method multi
* @param {Number} a First number
* @param {Number} b Second number
* @return {Number} The inputs multiplied
*/
multi: function (a, b) {
return a * b;
}
};
/**
* Constructs Person objects
* @class Person
* @constructor
* @namespace MYAPP
* @param {String} First name
* @param {String} Last name
*/
MYAPP.Person = function (first, last) {
/**
* First name of the Person
* @property first_name
* @type String
*/
this.first_name = first;
/**
* Last name of the Person
* @property last_name
* @type String
*/
this.last_name = last;
};
/**
* Return Person's full name
*
* @method getName
* @return {String} First name + last name
*/
MYAPP.Person.prototype.getName = function () {
return this.first_name + ' ' + this.last_name;
};
3
我用这种方法:
var myNamespace = {}
myNamespace._construct = function()
{
var staticVariable = "This is available to all functions created here"
function MyClass()
{
// Depending on the class, we may build all the classes here
this.publicMethod = function()
{
//Do stuff
}
}
// Alternatively, we may use a prototype.
MyClass.prototype.altPublicMethod = function()
{
//Do stuff
}
function privateStuff()
{
}
function publicStuff()
{
// Code that may call other public and private functions
}
// List of things to place publically
this.publicStuff = publicStuff
this.MyClass = MyClass
}
myNamespace._construct()
// The following may or may not be in another file
myNamespace.subName = {}
myNamespace.subName._construct = function()
{
// Build namespace
}
myNamespace.subName._construct()
外部代码可以是:
var myClass = new myNamespace.MyClass();
var myOtherClass = new myNamepace.subName.SomeOtherClass();
myNamespace.subName.publicOtherStuff(someParameter);
var namespace = {};
namespace.module1 = (function(){
var self = {};
self.initialized = false;
self.init = function(){
setTimeout(self.onTimeout, 1000)
};
self.onTimeout = function(){
alert('onTimeout')
self.initialized = true;
};
self.init(); /* If it needs to auto-initialize, */
/* You can also call 'namespace.module1.init();' from outside the module. */
return self;
})()
您可以选择声明一个 local 变量, same ,如 self ,如果您希望它是私有的,则分配 local.onTimeout .
88
您可以声明一个简单的函数来提供名称空间 .
function namespace(namespace) {
var object = this, tokens = namespace.split("."), token;
while (tokens.length > 0) {
token = tokens.shift();
if (typeof object[token] === "undefined") {
object[token] = {};
}
object = object[token];
}
return object;
}
// Usage example
namespace("foo.bar").baz = "I'm a value!";
55
如果您需要私人范围:
var yourNamespace = (function() {
//Private property
var publicScope = {};
//Private property
var privateProperty = "aaa";
//Public property
publicScope.publicProperty = "bbb";
//Public method
publicScope.publicMethod = function() {
this.privateMethod();
};
//Private method
function privateMethod() {
console.log(this.privateProperty);
}
//Return only the public parts
return publicScope;
}());
yourNamespace.publicMethod();
否则,如果你不会使用私人范围:
var yourNamespace = {};
yourNamespace.publicMethod = function() {
// Do something...
};
yourNamespace.publicMethod2 = function() {
// Do something...
};
yourNamespace.publicMethod();
(function(){
namespace("images", previous, next);
// ^^ This creates or finds a root object, images, and binds the two functions to it.
// It works even though those functions are not yet defined.
function previous(){ ... }
function next(){ ... }
function find(){ ... } // A private function
})();
32
我对命名空间使用以下语法 .
var MYNamespace = MYNamespace|| {};
MYNamespace.MyFirstClass = function (val) {
this.value = val;
this.getValue = function(){
return this.value;
};
}
var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
var Namespace = new function() {
var ClassFirst = this.ClassFirst = function() {
this.abc = 123;
}
var ClassSecond = this.ClassSecond = function() {
console.log("Cluttered way to access another class in namespace: ", new Namespace.ClassFirst().abc);
console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
}
}
var Namespace2 = new function() {
var ClassFirst = this.ClassFirst = function() {
this.abc = 666;
}
var ClassSecond = this.ClassSecond = function() {
console.log("Cluttered way to access another class in namespace: ", new Namespace2.ClassFirst().abc);
console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
}
}
new Namespace.ClassSecond()
new Namespace2.ClassSecond()
输出:
Cluttered way to access another class in namespace: 123
Nicer way to access a class in same namespace: 123
Cluttered way to access another class in namespace: 666
Nicer way to access a class in same namespace: 666
0
我们可以这样独立使用它:
var A = A|| {};
A.B = {};
A.B = {
itemOne: null,
itemTwo: null,
};
A.B.itemOne = function () {
//..
}
A.B.itemTwo = function () {
//..
}
Package("hello", [], function() {
function greeting() {
alert("Hello World!");
}
// Expose function greeting to other packages
Export("greeting", greeting);
});
文件Example.js
Package("example", ["hello"], function(greeting) {
// Greeting is available here
greeting(); // Alerts: "Hello World!"
});
27 回答
我喜欢这个:
我用the approach found on the Enterprise jQuery site:
以下是他们展示如何声明私有和公共属性和函数的示例 . 一切都是作为一个自动执行的匿名函数完成的 .
因此,如果您想访问其中一个公共成员,您只需要
skillet.fry()
或skillet.ingredients
.真正酷的是你现在可以使用完全相同的语法扩展命名空间 .
第三个未定义的参数
另一种方法,我认为它比对象文字形式的限制更少,是这样的:
上面的内容与the module pattern和whether you like it or not非常相似,它允许您将所有函数公开为public,同时避免对象文字的刚性结构 .
是 . 例如:
那么你可以拥有
我通常在一个闭包中构建它:
多年来我的风格在写这篇文章后发生了微妙的变化,现在我发现自己正在编写这样的闭包:
通过这种方式,我发现公共API和实现更容易理解 . 将return语句视为实现的公共接口 .
因为您可能会编写不同的JavaScript文件,然后在应用程序中组合或不组合它们,每个文件都需要能够恢复或构造命名空间对象而不会损坏其他文件的工作...
一个文件可能打算使用命名空间
namespace.namespace1
:另一个文件可能想要使用命名空间
namespace.namespace2
:这两个文件可以在一起或分开存在而不会发生冲突 .
以下是斯托扬·斯特凡诺夫(Stoyan Stefanov)在他的JavaScript Patterns书中的表现,我发现这本书非常好(它还展示了他如何做出允许自动生成API文档的注释,以及如何将方法添加到自定义对象的原型中):
我用这种方法:
外部代码可以是:
这是user106826指向Namespace.js的链接的后续内容 . 该项目似乎已移至GitHub . 它现在是smith/namespacedotjs .
我一直在为我的小项目使用这个简单的JavaScript助手,到目前为止,它看起来很轻但功能多,足以处理命名空间和加载模块/类 . 如果它允许我将一个包导入我选择的命名空间,而不仅仅是全局命名空间......叹息,那将是很棒的,但除此之外 .
它允许您声明命名空间,然后在该命名空间中定义对象/模块:
另一种选择是立即声明命名空间及其内容:
有关更多用法示例,请查看the source中的example.js文件 .
样品:
您可以选择声明一个
local
变量,same
,如self
,如果您希望它是私有的,则分配local.onTimeout
.您可以声明一个简单的函数来提供名称空间 .
如果您需要私人范围:
否则,如果你不会使用私人范围:
我创建了namespace,其灵感来自Erlang的模块 . 这是一种非常实用的方法,但这就是我最近编写JavaScript代码的方法 .
它为闭包提供了一个全局命名空间,并在该闭包中公开了一个已定义的set函数 .
我对命名空间使用以下语法 .
jsfiddle:http://jsfiddle.net/rpaul/4dngxwb3/1/
模块模式最初被定义为为传统软件工程中的类提供私有和公共封装的方法 .
使用Module模式时,我们可能会发现定义一个我们用于开始使用它的简单模板很有用 . 这是一个涵盖名称间距,公共和私有变量的 .
在JavaScript中,Module模式用于进一步模拟类的概念,使得我们能够在单个对象中包含公共/私有方法和变量,从而将特定部分与全局范围隔离开来 . 这导致我们的函数名称与其他脚本中定义的其他函数冲突的可能性降低页 .
Advantages
为什么模块模式是一个不错的选择?对于初学者来说,对于来自面向对象背景的开发人员来说,比真正封装的想法更加清晰,至少从JavaScript的角度来看 .
其次,它支持私有数据 - 因此,在模块模式中,代码的公共部分能够触及私有部分,但外部世界无法触及类的私有部分 .
Disadvantages
Module模式的缺点是,当我们以不同方式访问公共成员和私有成员时,当我们希望更改可见性时,我们实际上必须对使用该成员的每个位置进行更改 .
We also can't access private members in methods that are added to the object at a later point . 也就是说,在许多情况下,模块模式仍然非常有用,如果使用得当,肯定有可能改善我们的应用程序结构 .
The Revealing Module Pattern
现在我们对模块模式稍微熟悉一下,让我们看一下稍微改进的版本--Christian Heilmann的Revealing Module模式 .
揭示模块模式的出现是因为Heilmann对于当我们想要从另一个公共方法调用一个公共方法或访问公共变量时必须重复主对象的名称这一事实感到沮丧 . 他也不喜欢Module模式的必须切换的要求对他希望公开的事物反对文字符号 .
他努力的结果是一个更新的模式,我们将简单地定义私有范围中的所有函数和变量,并返回一个匿名对象,其中包含指向我们希望公开的私有功能的指针 .
An example of how to use the Revealing Module pattern can be found below
Advantages
此模式允许我们的脚本的语法更加一致 . 它还使模块结尾处的内容更加清晰,我们可以公开访问哪些函数和变量,从而简化了可读性 .
Disadvantages
这种模式的缺点是,如果私有函数引用公共函数,则如果需要补丁,则不能覆盖该公共函数 . 这是因为私有函数将继续引用私有实现,并且该模式不适用于公共成员,仅适用于函数 .
引用私有变量的公共对象成员也受上面的无补丁规则说明的约束 .
在将我的几个库移植到不同的项目之后,不得不经常更改顶级(静态命名)命名空间之后,我转而使用这个小的(开源)辅助函数来定义命名空间 .
福利的描述在我的blog post . 你可以 grab source code here .
我真正喜欢的一个好处是模块之间的负载顺序隔离 . 您可以在加载外部模块之前参考它 . 当代码可用时,您将获得对象引用 .
我在晚会上已经晚了7年,但是在8年前做了很多工作:
http://blogger.ziesemer.com/2008/05/javascript-namespace-function.html
http://blogger.ziesemer.com/2007/10/respecting-javascript-global-namespace.html
能够轻松高效地创建多个嵌套命名空间以保持复杂Web应用程序的组织和可管理性,同时尊重JavaScript全局命名空间(防止名称空间污染),并且在执行此操作时不破坏命名空间路径中的任何现有对象,这一点非常重要 . .
从上面来看,这是我的大约2008年的解决方案:
这不是创建命名空间,而是提供创建命名空间的功能 .
这可以浓缩为缩小的单行:
使用示例:
或者,作为一个声明:
然后执行任何一个:
如果您不需要对旧版浏览器的支持,请更新以下版本:
现在,我对将
namespace
暴露给全局命名空间本身持怀疑态度 . (太糟糕了,基本语言通常不会在闭包中使用它,例如:在较大的应用程序中,这只需要在页面加载开始时定义一次(对于基于客户端的Web应用程序) . 如果保留了附加文件,则可以重用命名空间功能(在上面包含为“可选”) . 在最坏的情况下,如果重新声明此函数几次 - 它只是几行代码,如果缩小则更少 .
你必须检查Namespace.js!
我最喜欢的模式最近变成了:
当然,返回可以在最后,但如果只有函数声明跟随它,则更容易看到命名空间的全部内容,以及暴露的API .
在这种情况下使用函数表达式的模式导致无法在不遍历整个代码的情况下知道暴露了哪些方法 .
我喜欢Jaco Pretorius的解决方案,但我希望通过将它指向模块/命名空间对象来使“this”关键字更有用 . 我的煎锅版本:
接下来是IonuţG . Stan的回答,但是通过使用
var ClassFirst = this.ClassFirst = function() {...}
显示了整洁代码的好处,它充分利用了JavaScript的闭包范围,减少了名称空间的混乱 . 同一命名空间中的类 .输出:
我们可以这样独立使用它:
我认为你们都为这样一个简单的问题使用了太多的代码 . 没有必要为此做回购 . 这是一个单行功能 .
试试吧 :
如果使用Makefile,您可以执行此操作 .
一旦我达到大约1000行,我更喜欢使用Makefile,因为我可以通过删除makefile中的一行来有效地注释掉大量的代码 . 它可以很容易地摆弄东西 . 此外,使用此技术,命名空间仅在前奏中出现一次,因此它很容易更改,您不必在库代码中继续重复它 .
使用makefile时在浏览器中进行实时开发的shell脚本:
将其添加为make任务'go',您可以'make go'在编码时保持您的构建更新 .
我已经编写了另一个命名空间库,它的工作方式与其他语言的包/单元相似 . 它允许您创建一个JavaScript代码包和来自其他代码的包的引用:
文件hello.js
文件Example.js
只需要在页面中包含第二个文件 . 它的依赖项(本例中的文件hello.js)将自动加载,从这些依赖项导出的对象将用于填充回调函数的参数 .
您可以在Packages JS中找到相关项目 .
我的习惯是使用函数myName()作为属性存储,然后将var myName作为"method" holder ...
这是否合法,打败我!我一直依赖于我的PHP逻辑,而且事情很简单 . :d
if (this !== that) myObj.fName1(); else myObj.fName2();
参考:JavaScript: Creating Object with Object.create()
在JavaScript中,没有预定义的方法来使用名称空间 . 在JavaScript中,我们必须创建自己的方法来定义NameSpaces . 以下是我们在Oodles技术中遵循的程序 .
注册NameSpace以下是注册名称空间的功能
要注册一个命名空间,只需调用上面的函数,并将参数作为名称空间,用
'.'
(点)分隔 . 例如,让您的应用程序名称为oodles . 您可以通过以下方法创建命名空间基本上它会在后端创建如下所示的NameSpaces结构:
在上面的函数中,您注册了一个名为
"oodles.HomeUtilities"
和"oodles.GlobalUtilities"
的命名空间 . 要调用这些名称空间,我们创建一个变量,即var$OHU
和var$OGU
.这些变量只不过是初始化命名空间的别名 . 现在,每当您声明属于
HomeUtilities
的函数时,您将声明如下:上面是函数名称初始化,它被放入命名空间
$OHU
. 并在脚本文件中的任何位置调用此函数 . 只需使用以下代码 .同样,与另一个NameSpaces .
希望能帮助到你 .