如何正确设置JavaScript名称空间和类?

似乎有很多方法来设置一个JavaScript应用程序,所以它是混淆的,哪一个是正确的或最好的。 下面的技术有什么区别或者更好的方法吗?

MyNamespace.MyClass = { someProperty: 5, anotherProperty: false, init: function () { //do initialization }, someFunction: function () { //do something } }; $(function () { MyNamespace.MyClass.init(); }); 

其他方式:

 MyNamespace.MyClass = (function () { var someProperty = 5; var anotherProperty = false; var init = function () { //do something }; var someFunction = function () { //do something }; return { someProperty: someProperty anotherProperty: anotherProperty init: init someFunction: someFunction }; }()); MyNamespace.MyClass.init(); 

第一种技巧更像是一堂课。 如果这有所作为,我来自服务器端的背景。 第二种技术似乎更加多余,有点尴尬,但是我也看到了这一点。 有人能帮助摆脱一些光线,并build议最好的方式前进? 我想要创build一个有很多类互相交谈的应用程序。

不要做那些事情。

制作一个JavaScript“类”:

 var MyClass = function () { var privateVar; //private var privateFn = function(){}; //private this.someProperty = 5; //public this.anotherProperty = false; //public this.someFunction = function () { //public //do something }; }; MyNamespace.MyClass = new MyClass(); 

一个与静态variables:

 var MyClass = (function(){ var static_var; //static private var var MyClass = function () { var privateVar; //private var privateFn = function(){}; //private this.someProperty = 5; //public this.anotherProperty = false; //public this.someFunction = function () { //public //do something }; }; return MyClass; })(); MyNamespace.MyClass = new MyClass(); 

用“构造函数”(所有的例子都有一个“构造函数”,这个只有参数可以使用):

 var MyClass = function (a, bc) { //DO SOMETHING WITH a, b, c <-- var privateVar; //private var privateFn = function(){}; //private this.someProperty = 5; //public this.anotherProperty = false; //public this.someFunction = function () { //public //do something }; }; MyNamespace.MyClass = new MyClass(1, 3, 4); 

以上所有你可以做

 MyNamespace.MyClass.someFunction(); 

但是你不能 (从外面)做:

 MyNamespace.MyClass.privateFn(); //ERROR! 

第一个例子只是一个对象字面值 – 它不能被实例化,也没有私有成员。 第二个例子有一些不正确的语法( var someProperty: 5应该是var someProperty = 5 ),但是使用闭包来将内部私有状态封装在一个自我调用的匿名函数中。

第二种方法看起来好于封装私有成员,但是通过使其成为一个可实例化的类,可以使其更“面向对象”:

 MyNamespace.MyClass = function() { ... }; MyNamespace.MyClass.prototype.someProperty = 'foo'; 

然后你可以用“new”关键字来实例化它:

 var aClass = new MyNamespace.MyClass(); aClass.init(...); 

我使用下面的语法为名称空间的可实例化的类

  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()); 

jsfiddle: http : //jsfiddle.net/rpaul/4dngxwb3/1/

为什么你不应该使用

  return { methodName : methodDelegate} 

就像第二个例子:

 MyNamespace.MyClass = (function () { var someProperty = 5; var init = function () { //do something }; return { someProperty: someProperty someFunction: someFunction }; }()); MyNamespace.MyClass.init(); 

当你使用命名空间时,你必须把它看作是声明而不是实例。

 MyNamespace = {}; MyNamespace.sub = {}; MyNamespace.anotherSub = {}; MyNamespace.sub.MyClass = (function () { var static_var; //static private var var MyClass2 = function () { var privateVar; //private var privateFn = function () { }; //private this.someProperty = 5; //public this.anotherProperty = false; //public this.someFunction = function () { //public //do something }; }; return MyClass2; })(); debugger; var c1 = new MyNamespace.sub.MyClass(); c1.someProperty = 1; // creates 5->1. var c2 = new MyNamespace.sub.MyClass(); c2.someProperty = 2; // creates 5->2. c1 is still 1 debugger; var myClass = function () { var someProperty = 5; var anotherProperty = false; var init = function () { //do something }; var someFunction = function () { //do something }; return { someProperty: someProperty, anotherProperty: anotherProperty, init: init, someFunction: someFunction }; }; MyNamespace.MyClass = myClass(); var c2 = MyNamespace.MyClass; // how are planning to create one more object, while it's a reference? copy //the whole one? c2.someProperty = 2; // changes 5 -> 2 var c3 = MyNamespace.MyClass.init(); // create 2 instead of 5 c3.someProperty = 3; // changes c3 and c3 from 2 to 3. console.log(c2.someProperty + c3.someProperty); 

没有metter多less模块反patterstream行。 声明使您能够以其他开发人员所期望的方式对不同实例使用相同的代码。 代码的质量和简单的阅读增加。 任何开发人员的目标都是编写一个简单的代码来读取,而不是简单的或干的 – 但很容易被其他开发人员阅读和理解。 这首先减less了错误的数量。 (c)S.McConnell

如何结合命名空间和类声明:

 var ns = { // your namespace my_value: 1, // a value inside the namespace to avoid polluting MyClass: function() { // a class inside the namespace this.class_property: 12, this.class_method: function() { console.log("My property: " + this.class_property); } }, myFunction: function() { // a function inside a namespace console.log("I can access namepsace value if you don't use 'new': " + this.my_value); } }; 

访问您的价值:

 console.log(ns.my_value); 

现在,对于类和函数:如果你使用newthis函数内的这个词将指向它的构造函数。 如果你不使用newthis将指向命名空间。 所以,

使用一个类:

 var obj = new ns.MyClass(); 

使用function:

 ns.myFunction(); 

如果你没有new构造对象, this将指向命名空间,所以命名空间将被“销毁”,因为MyClass.class_propertyMyClass.class_method将被添加到它。

Interesting Posts