JavaScript命名空间

分享于 

8分钟阅读

Web开发

  繁體 雙語

介绍

任何来自 C#,Java background的人都知道命名空间的重要性。 这是让你的代码保持有序的主要方法。 JavaScript不支持命名空间,也不支持命名空间?

对象嵌套

JavaScript是一种动态语言。 可以动态创建对象,而对象可以包含其他对象。 这个概念将允许创建模拟命名空间的Prototype结构。

让我们看看哺乳动物,cat 和狗的例子

var Animal=function() {
 //we don't know yetthis.numberOfLegs=null;
 this.sound=null;
 returnthis;
}
Animal.prototype.getNumberOfLegs=function() {
 returnthis.numberOfLegs;
}
Animal.prototype.makeSound=function() {
 alert(this.sound);
}var Mammal=function() {
 //all mammals have for legs;this.numberOfLegs=4;
 returnthis;
 }
Mammal.prototype=new Animal();var Dog=function() {
 this.sound="Woef";
}
Dog.prototype=new Mammal();var Cat=function() {
 this.sound="Miauw";
 returnthis;
}
Cat.prototype=new Mammal();var Tiger=function() {
 this.sound="Wroaar";
 returnthis;
}
Tiger.prototype=new Mammal();var Leopard=function() {
 this.sound="Grrrr";
 returnthis;
}
Leopard.prototype=new Mammal();

这很好。我们可以创建所有的哺乳动物,我们可以为鸟类 等等 建立一个基类。 但是如果我们还需要保留 List 名称的。 我们需要 List 和 Leopard的苹果。

接下来让我们认为 Animal 是一个你不应该直接使用的类。 我倾向于把这些类称为。 但是没有命名空间我只能有一个基础。

总之,我们希望在 Animals 命名空间中创建我们的动物。 允许使用 IOS namespace that also has Tiger & Leopard 和基类。 我们欺骗JS模仿名称空间的方式是创建嵌套对象。 在那里我们放置其他物体。

//Create the Animals namespaceif(typeof Animals=='undefined') {
 window["Animals"]={}; 
}
Animals.Base=function() {
 //we don't know yetthis.numberOfLegs=null;
 this.sound=null;
 returnthis;
}
Animals.Base.prototype.getNumberOfLegs=function() {
 returnthis.numberOfLegs;
}
Animals.Base.prototype.makeSound=function() {
 alert(this.sound);
}
Animals.Mammal=function() {
 //all mammals have for legs;this.numberOfLegs=4;
 returnthis;
 }
Animals.Mammal.prototype=new Animals.Base();
Animals.Dog=function() {
 this.sound="Woef";
 returnthis;
}
Animals.Dog.prototype=new Mammal();//...etc

注意'var'的省略。 我们要做的是将所有内容添加到全局命名空间。 有些被认为是否定的,但它确实是 jQuery。EXTJS。YUI 和Prototype所做的。 实际上,如果将所有类甚至函数放在单个名称空间中,那么就说你的产品名,这样你就可以防止污染全局名称空间。

另外,我倾向于将所有代码打包在一个匿名函数中,js。js文件。 这样,你就可以拥有只有 inside的'全局'变量,并且它们不会污染全局名称空间。

(function() {
 //Create OurProduct namespaceif(typeof OurProduct=='undefined') {
 window["OurProduct"]={}; 
 }
 var someVariableAvailableToAllClassesWithinThisFunctionButNotOutside="Hello";
 //Create the Animals namespace inside the OurProduct namespaceif(typeof OurProduct.Animals=='undefined') {
 window["OurProduct"]["Animals"]={}; 
 }
 OurProduct.Animals.Base=function() {
 //we don't know yetthis.numberOfLegs=null;
 this.sound=null;
 returnthis;
 }
. . .....
})();//Note the () at the end. If you omit that this code will never be run.

register 命名空间

命名空间实际上仅仅是创建嵌套对象。 由于窗口本身是一个对象,实际上可以直接创建对象。 但如果我们想在非现有的嵌套命名空间中创建一个对象,我们需要先创建一个。

MyProduct.Objects.Person=function() {
 //This will fail, because MyProduct.Objects doesn't yet exist.}

我们希望有一个像这样的函数 NameSpace.register("MyProduct.Object") 让我们来创建。

(function() {
 Namespace = {
 register : function(ns) {
 //Split the stringvar nsParts=ns.split(".");
 //Store window in objvar obj=window;
 //Travese through the string partsfor(var i=0, j=nsParts.length; i<j; i++) {
 if(typeof obj[nsParts[i]] == "undefined") {
 //Is it did not exist create it and copy it to obj//so the next part can be copied into this part. obj=obj[nsParts[i]]={};
 }
 else {
 //Still copy it to obj, cause the next one might not exist obj=obj[nsParts[i]];
 }
 }
 }
 }
 NameSpace.register("MyProduct.Objects");
 MyProduct.Objects.Person=function() {
 alert("yeee this is legal")
 } 
 var P=new MyProduct.Objects.Person();
})();

这是在某个地方,我已经在我的项目中获得了一些精确的功能。 在我开始思考之前,我的C# 代码旁边的"由于我总是将类包装在匿名函数中,所以为什么不使函数有用"看起来像这样:?

namespace MyProduct.Objects {
 publicclass Person {
. . ..
 }
}

当然,我们不能并且不应该尝试使代码看起来完全相同,但是我们可以有一些类似的。

Namespace("MyProject.Objects", function() {
 MyProduct.Objects.Person=function() {
. . .. 
 }
});//notice the omission of the ()//starting the function will be a task of the namespace function

那我们该怎么做? 让我们创建命名空间函数:

//This function itself is'nt Namespaced so it should be wrapped in an anonymous function(function() {
 //no var so it will end up in the global namespace Namespace=function(ns, fs) {
 //ns Namespace as. seperated string//fs the return function//Here's our trusty register function, only now it's inline var register = function(ns) {
 //Split the stringvar nsParts=ns.split(".");
 //Store window in objvar obj=window;
 //Travese through the string partsfor(var i=0, j=nsParts.length; i<j; i++) {
 if(typeof obj[nsParts[i]] == "undefined") {
 //Is it did not exist create it and copy it to obj//so the next part can be copied into this part. obj=obj[nsParts[i]]={};
 }
 else {
 //Still copy it to obj, 'cause the next one might not exist obj=obj[nsParts[i]];
 }
 }
 } 
 //Let's register the namespace register(ns);
 //And call the wrapper function.  fs(); 
 };
})();

我在名称空间的第一个字母中使用大写字母。 通常我会用 lowercase 启动一个函数。 但例如class是一个保留字。 所以我害怕命名空间将来可能成为一个保留字。

结束语

许多JavaScript被认为不是'真实'语言。 但不管你的观点是什么,只要开始使用长函数链,然后在它的他的页面代码中就可以了。 当你运行任何可以能被认为有状态的东西时,你需要开始考虑创建对象。 当你到达那里时,你需要一个名字空间来把它们放在。 首先看起来很幽默,但是代码库越大,它的意义就越大。


相关文章