在C++和C#中,命名空间用于尽可能地减少名称冲突。例如,在.NET Framework中,命名空间有助于将Microsoft.Build.Task.Message类与System.Messaging.Message区分开来。JavaScript没有任何特定语言功能来支持命名空间,但很容易使用对象来模拟命名空间。如果要创建一个JavaScript库,则可以将它们包装在命名空间内,而不需要定义全局函数和类,如下所示:
var MSDNMagNS.Pet = function(name) { // code here; }; MSDNMagNs.Pet.prototype.toString = function() { // code }; var pet = new MSDNMagNS.Pet("Yammer"); 命名空间的一个级别可能不是唯一的,因此可以创建嵌套的命名空间:
var MSDNMagNS = {}; // nested namespace "Examples" MSDNMagNS.Examples = {}; MSDNMagNS.Examples.Pet = function(name) { // code }; MSDNMagNS.Examples.Pet.prototype.toString = function() { // code }; var pet = new MSDNMagNS.Examples.Pet("Yammer"); 可以想象,键入这些冗长的嵌套命名空间会让人很累。幸运的是,库用户可以很容易地为命名空间指定更短的别名:
// MSDNMagNS.Examples and Pet definition... // think "using Eg = MSDNMagNS.Examples;" var Eg = MSDNMagNS.Examples; var pet = new Eg.Pet("Yammer"); alert(pet); 如果看一下Microsoft Ajax库的源代码,就会发现库的作者使用了类似的技术来实现命名空间(请参阅静态方法Type.registerNamespace的实现)。 OOP 和 ASP.NET AJAX 在ASP.NET AJAX中实现的OOP与在本文中讨论的规范实现稍有不同,这主要有两个原因:ASP.NET AJAX版本提供了更多反射可能性(它是诸如 xml 脚本等声明性语法和参数验证所必需的),而且ASP.NET AJAX的目标是将使用.NET的开发人员所熟悉的某些其它构造(例如属、事件、枚举和接口)转换成JavaScript。 在JavaScript当前广泛使用的版本中,它缺少.NET开发人员所熟悉的几个OOP的关键概念,而ASP.NET AJAX可以模拟其中的大多数。 根据命名约定(要遵守的示例),类可以有属性访问器,以及多播事件(符合紧密反映由.NET提供的约定的模式)。私有变量遵守成员以下划线开头则为私有的约定。很少有机会用到真正的私有变量,此策略是为了使调试程序能够监测到这些变量。引入接口也是为了使类型检查能够避免常见的鸭子定型法(一种类型方案,它基于的概念是:如果有什么物体走路和叫声像鸭子,那么它就是鸭子,或至少可以将它视为鸭子)。 类和反射 在JavaScript中,没有办法知道函数的名称。即使这是可能的,但在大多数情况下也没有什么用,因为类构造函数通常是通过向命名空间变量分配匿名函数来构造的。实际构成类型名称的是此变量的完全限定名称,它同样不可访问,并且构造函数本身对它一无所知。为了规避此限制,并使JavaScript类有丰富的反射,ASP.NET AJAX需要将类型名称进行注册。 ASP.NET AJAX中反射的API将检查所有类型(无论是内置类型、类、接口、命名空间或者甚至是枚举),而它们包括的类似.NET Framework 的函数(例如 isInstanceOfType和inheritsFrom)可以在运行时检查类的层次结构。ASP.NET AJAX 还会在调试模式下执行某些类型检查,这对开发人员更早的捕获Bug很有帮助。 注册类层次结构和调用基础函数 若要在ASP.NET AJAX中定义类,您需要将其构造函数赋给变量(注意,构造函数如何调用举出函数):
|
|