65.9K
CodeProject 正在变化。 阅读更多。
Home

jOOPL:JavaScript 的面向对象编程

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2013 年 1 月 30 日

Apache

4分钟阅读

viewsIcon

32375

发现一种现代化、稳健且强大的方式,可以在 Web 和任何地方利用面向对象编程

引言

在过去十年中,Web 开发的复杂性不断增加。想想 Web 的过去和现在的变化:Web 应用。也称为 Web 2.0 和即将到来的 3.0。

JavaScript 始终是陪伴 Web 从早期阶段至今的语言。曾经,它是为我们的页面添加一些花哨效果的方式,但随着语言发展成为真正的应用程序编程语言,重用和扩展的需求已成为 Web 开发中的重要一点。

毫无疑问,面向对象的方法在图形用户界面、域和其他方面,已经证明它是创建结构良好、可重用且易于维护的软件的好方法。

最糟糕的是 JavaScript 不是一门面向对象编程语言:它是面向原型,这是一种利用完整面向对象平台少部分功能的薄弱方法。

这就是 jOOPL 存在的原因 (Codeplex 官方网站)。"jOOPL" 代表 "JavaScript Object-Oriented Programming Library"。它就是这样:一个轻量级、易于使用且纯面向对象的编程库,允许纯 JavaScript 利用更高级的功能,例如

  • 继承
  • 多态
  • 封装
  • 组成

并且仅此而已。jOOPL 不执行诸如

  • DOM 操作
  • DOM 事件处理
  • AJAX

最后,jOOPL 完全开源,并获得 Apache v2 许可证。

Using the Code

让我们创建一个非常简单的示例,展示在纯标准 JavaScript 中使用 jOOPL 的面向对象编程的强大功能。

想想关于二维多边形非常常见的示例:三角形、正方形、五边形……它们都是多边形,并且它们有不同的公式来计算它们的面积。也就是说,应该有一个名为 Polygon 的类,其中有一个多态方法来计算整个面积

// First of all, we are going to declare a namespace for the class
$namespace.register("Joopl.Samples");

// Next part will be about designing the whole class
Joopl.Samples.Polygon = $class.declare(
// The constructor
function() {
    // This is very recommended: if you declare a class field in the constructor,
    // it will hold a default value instead of undefined
    this.$_.args = null;
},
{
  // Sets an object that will hold the arguments to calculate the polygon's area
  set_Args: function(value) {
    this.$_.args = value;
  },
  
  // Gets an object that will hold the arguments to calculate the polygon's area
  get_Args: function() {
    return this.$_.args;
  },
  
  // The method to calculate the area. Check that its body does implement nothing.
  // Derived classes will be the ones responsible for providing the formula to make the calculation.
  CalculateArea: function() {
  }
}
);

$namespace,$class… 但那是什么?在 jOOPL 中,有一些保留关键字。它们都以美元符号($)开头。其中一些将是快捷函数或完整对象。

在我们的例子中,$namespace$class 是关键字,它们包含一个对象来管理 JavaScript 代码中的这两种实体(命名空间和类)。

任何代码文件都应该注册它所属的命名空间。如果该命名空间之前已被声明,jOOPL 将直接跳过命名空间注册。命名空间是 JavaScript Web 浏览器脚本中最顶层的 Window 对象的子对象。

实际上,类可以被声明并存储在常规变量中,但 jOOPL 鼓励不要这样做,以避免命名冲突。 

关于类声明,$class 关键字包含一个类管理对象,在这种情况下,我们正在使用 declare 方法。它可以接受以下参数(按顺序)

  1. classConstructor(必需):代表类构造函数的函数。jOOPL 不支持每个类有多个构造函数
  2. methods(必需):一个函数对象映射,代表类的各种方法或行为
  3. baseClass(可选):要继承的基类。jOOPL 不支持多重继承。
  4. interfaces(可选):类必须实现的一个或多个接口

实现多边形...

现在,假设我们想实现 Rectangle 多边形。为了正确实现它,我们需要: 

  1. rectangle 的测量值(xy
  2. 覆盖 CalculateArea 以实现 Rectangle 特定的面积计算
$namespace.register("Joopl.Samples");
  
Joopl.Samples.Rectangle = $class.declare(
function() { },
{
    CalculateArea: function() {
        if(this.get_Args() && this.get_Args().x && this.get_Args().y) {
          return this.get_Args().x * this.get_Args().y;
        }
        else {
          throw Error("Please give X and Y!");
        }
    }
},
Joopl.Samples.Polygon
);

// Using the $new keyword and shortcut function, we instantiate
// a rectangle and later we set the arguments to calculate the area
var someRectangle = $new(Joopl.Samples.Rectangle);
someRectangle.set_Args({ x: 10, y: 20 });

// This calls the whole method and calculates the area. For now,
// nothing will be shown in the document: it is just getting the result.
var result = someRectangle.CalculateArea();

上面的代码并没有证明多态性(但它证明了继承)。现在让我们想象一下,我们在基类中添加了一个名为 OutputArea 的新方法,该方法将计算某个多边形面积的结果写入文档。

$namespace.register("Joopl.Samples");
  
Joopl.Samples.Polygon = $class.declare(
function() {
    this.$_.args = null;
},
{
  set_Args: function(value) {
    this.$_.args = value;
  },
  
  get_Args: function() {
    return this.$_.args;
  },
  
  CalculateArea: function() {
  },
  
  // This is the new method. It calculates the area and writes the result into the document! 
  OutputArea: function() {
    document.write(this.$_.$derived.CalculateArea());
  }
}
);

// Using the $new keyword and shortcut function, we instantiate a rectangle
// and later we set the arguments to calculate the area again!
var someRectangle = $new(Joopl.Samples.Rectangle);
someRectangle.set_Args({ x: 10, y: 20 });
  
// This calls the whole method and calculates the area and finally writes the result to the document.
someRectangle.OutputArea();

OutputArea 写入调用 CalculateArea 方法更专业版本的结果。

如上面的代码所示,jOOPL 提供了保留的内置 this.$_.$derived 字段,以便访问派生类的成员。作为基类的一部分访问方法(例如 this.CalculateArea())仍然有效,但它调用的是封闭类的版本。 

jsFiddle 上实时查看此示例(请关注链接)。 

结语

这是 jOOPL 潜力的一个小示例。jOOPL 支持几乎所有面向对象编程的特性,并为 JavaScript 带来了其巨大的优势。

因为它不使用任何 Web 浏览器功能——只使用纯 JavaScript——jOOPL 可以在任何 JavaScript 解释器或编译器中运行,这意味着 jOOPL 是 JavaScript 面向对象编程的一个平台无关的解决方案!

如果您想了解更多关于其功能的信息并了解如何利用它,请访问 CodePlex 上的 jOOPL 官方网站

也欢迎合作和反馈。

历史

  • 2013 年 1 月 30 日:初始版本
© . All rights reserved.