使用function-prototype声明Javascript命名空间
Javascript namespace declaration with function-prototype
我知道,这是经常讨论的。但在像19世纪的人一样四处搜寻之后,我需要一些建议。声明"名称空间"对我来说没有问题,但是当涉及到原型时。foo函数,我卡住了。我找到了一个方法,但我不喜欢它:
Namespace = {}
Namespace.obj = function() {
this.foo="bar";
}
Namespace.obj.prototype.start = function() {
this.foo="fubar";
}
blah = new Namespace.obj();
blah.start();
现在,由于我对脚本的情况有点神经质,我希望有这样的东西:
Namespace = {
obj: function() {
this.foo="bar";
},
obj.prototype.start: function(tabinst) {
this.foo="fubar";
}
}
...
然后抛出一个错误:"Uncaught SyntaxError: Unexpected token ."
我知道,这是装饰,但我认为必须有一个更好的方法来声明一个包含类和原型函数的"命名空间"。
我的方法是使用"Module pattern"。
你基本上把所有的"模块"逻辑封装在一个自执行的函数中,这个函数会返回一个包含你的类、函数、变量等的对象。将返回值视为暴露模块API。
Namespace = (function () {
/** Class obj **/
var obj = function () {
this.foo = 'bar';
};
obj.prototype = {
start: function () {
this.foo = 'fubar';
}
};
/** Class obj2 **/
var obj2 = function () {
this.bar = 'foo'
};
obj2.prototype = {
start: function () {
this.bar = 'barfoo';
},
end: function () {
this.bar = '';
}
};
return {
obj : obj,
obj2: obj2
};
})();
var o = new Namespace.obj()
o.start()
为了进一步封装"obj"类方法和构造函数,我们可以这样做:
/** Class obj **/
var obj = (function () {
/** class Constructor **/
var obj = function () {
this.foo = 'bar';
};
/** class methods **/
obj.prototype = {
start: function () {
this.foo = 'fubar';
}
};
return obj;
})();
使用这种模式还有一个免费的重要特性,那就是"私有变量",考虑如下:
/** Class Foo **/
var Foo = (function () {
// Private variables
var private_number = 200
/** class Constructor **/
var Foo = function () {
this.bar = 0;
};
/** class methods **/
Foo.prototype = {
add: function () {
this.bar += private_number;
}
};
return Foo;
})();
foo = new Foo();
alert(foo.bar); // 0
foo.add();
alert(foo.bar);// 200
alert(foo.private_number) //undefined
可以,因为你不能在对象声明中使用这种类型的链接
obj。原型或对象。因为语言将obj视为非对象值。你可以创建这样的效果
Namespace = {};
Namespace.obj =function() {
this.foo="bar";
};
Namespace.obj.prototype.start = function(tabinst) {
this.foo="fubar";
};
console.log( Namespace.obj.prototype );
(参见此提琴http://jsfiddle.net/WewnF/)
编辑:哇,我刚刚注意到我所说的已经在这个问题中了。我很抱歉没有早点注意到……你描述自己的方式是实现这个目标的正确方法。
否则你可以像这样重写你的代码——但这不是你想要的,也不会工作一样(因为obj本身不是一个函数,你必须调用它的主函数,就像obj.main();)
Namespace = {
obj: {
main : function() {
this.foo="bar";
},
prototype : {
start: function(tabinst) {
this.foo="fubar";
}
}
}
}
编辑2:看这个提琴http://jsfiddle.net/NmA3v/1/
Namespace = {
obj: function() {
this.foo="bar";
},
prototype: {
obj : {
start : function( hi ) {
alert( hi );
}
}
},
initProto : function(){
for( var key in Namespace )
{
if( key !== "prototype" )
{
for( var jey in Namespace.prototype[ key ] )
Namespace[ key ].prototype[ jey ] = Namespace.prototype[ key ][ jey ];
}
}
}
}
Namespace.initProto();
console.log( Namespace.obj);
var test = new Namespace.obj();
test.start( "Hello World" );
这将具有完全相同的效果。解释:我们将对象声明为普通的属性函数,然后使用一个主原型对象,该对象包含与上面相同名称的对象,例如每个命名空间。还有一个namspace .prototype.obj,它包含了我们想要添加到原型链中的函数。
然后使用namspace . protoinit(),我们遍历所有属性-并从命名空间中提取函数。原型[key]并将它们添加到命名空间[key]。成功扩展了原型对象!有点不正统,但是有效!
只是为了刺激和扩展上面的答案。基于嵌套命名空间
的更多面向对象表示法var NS = {};
// Class List
NS.Classes = {
Shape: (function(){
// Private
var whateveryouwishboss = false;
// Public
var Shape = function(x,y,w,h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
};
Shape.prototype = {
draw: function(){
//... Im on prototype Shape
}
}
return Shape;
})(),
Person: (function(){
//....
})()
}
/////// Let the games begin
var rect = new NS.Class.Shape(0,0,10,10);
rect.draw()
- 在javascript中使用命名空间
- javascript中的命名空间,IDE中支持代码完成/内容辅助's
- 如何使用javascript命名空间
- 转换自的JavaScript命名空间
- 什么's当前命名空间/类中JavaScript子命名空间/类的语法
- 在Firebug控制台中监视javascript命名空间变量
- 用自定义javascript全局命名空间替换窗口
- 怎么了?通过字符串定义 JavaScript 命名空间
- Javascript 命名空间/最佳实践
- IE中的Javascript命名空间抛出错误
- 处理此命名空间 JavaScript 结构的最佳方法是什么?
- 将 JavaScript 封装在命名空间中
- 将索引值传递给javascript命名空间数组
- JavaScript风格:我应该将这些东西中的哪些作为参数传递给我的命名空间函数
- 如何正确设置 JavaScript 命名空间和类
- 创建命名空间 Javascript 单例类的对象
- Xmlns 命名空间 JavaScript 删除
- 在我的命名空间JavaScript中使用this关键字
- 命名空间Javascript中的递归函数
- 构造函数-在简单的命名空间- Javascript