JS.Class - 1. Classes & Inheritance


对于 JavaScript,我是既爱又头疼。喜欢它的简洁和灵活性,头疼那 "面向过程" 的开发方式。也正因为如此,我曾在相当长的时间里拒绝使用它。对于一个习惯了 OO 思想的人来说,将数据和行为分离的编码风格纯粹是一种痛苦折磨。混乱的 HTML 加上同样乱糟糟的 .js,让我无时无刻不觉得那是一块沼泽地。兴许是完美主义洁癖在作怪,new function、对象冒充、原型链,亦或者李战大侠的 "甘露模型" 都不太符合我的要求。面向对象并不仅仅是对象和继承,它还包括更多的东西。总算是功夫不负有心人,JS.Class —— Ruby-like classes for JavaScript 几乎完美地做到了这些,同时也让我见识了 JavaScript 的强大。

  JS.Class 库被设计用来简化 JavaScript 面向对象开发,它借鉴了 Ruby 的几种风格来模拟 Classes、Inheritance、Mixins 以及 Modules。(尽管作者在介绍里使用 "simulate" 这个词,但我觉得这更像是 DSL 的一种)

  首先我们看一个简单的演示。

var User = new JS.Class(
{
  initialize : function(name) 
  {
    if (name != undefined) this.name = name;
  },
  name : "Anonymous",
  age : 0,
  sex : "UnKnown",
  getInfo : function() 
  {
    return "Name: " + this.name + "; Age: " + this.age + "; Sex: " + this.sex;
  },
  
  show : function(content)
  {
    alert("<User>\r\n" + content);
  }
});
var user = new User("Tom");
user.age = 30;
user.sex = "Female";
var info = user.getInfo();
user.show(info);

嗯~~~ 这应该说是创建一个类对象,而非类定义。JSON 方式看上去简洁美观,JS.Class 接收一个定义对象来完成 Class 定义。initialize 可以理解为实例初始化方法 (.ctor),它包含了构造一个对象所需的参数/属性。调用代码完全类似 C#/Java 风格,熟悉的 new 关键字以及成员调用。

  创建一个继承子类同样很简单。

var Manager = new JS.Class(User, 
{
  initialize : function(name, address)
  {
    this.callSuper();
    this.address = address;
  },
  
  address : "UnKnown",
  
  test : function() 
  { 
    alert(this.name); 
  },
  show : function(content) 
  { 
    content += " (Manager)";
    this.callSuper(content); 
  }
});
var user = new Manager("Tom");
user.age = 30;
user.sex = "Female";
var info = user.getInfo();
user.show(info);

  JS.Class 通过接收基类对象和新增成员对象两个参数来创建子类。除了新增成员外,我们还可以 override 基类的方法。这里面出现了一个 callSuper() 方法,作用类似 C# 里面的 base,它可以自动处理方法参数并调用基类方法。不过需要注意的是,如果我们修改了参数,那么必须显式添加调用参数。

  看看不显示添加调用参数的结果。

show : function(content) 
{ 
  content += " (Manager)";
  this.callSuper(); 
}

  输出:

<User>
Name: Tom; Age: 30; Sex: Female


  子类的初始化方法不是必须的,但如果需要,同样可以重写。

  JS.Class 还允许我们创建静态方法 (static method),这是其他 JavaScript OO 模型所没有的。

var User = new JS.Class(
{
  initialize: function(name) 
  {
    this.name = name;
  },
  extend:
  {
    getInfo: function(user)
    {
      return user.name;
    },
    show: function(s)
    {
      alert(s);
    }
  }
});
  
var Manager = new JS.Class(User, 
{
  initialize : function(name, age)
  {
    this.callSuper(name);
    this.age = age;
  },
  extend:
  {
    getInfo : function(user)
    {
      return this.callSuper() + ";" + user.age;
    }
  }
});
  
var manager = new Manager("Tom", 31);
var info = Manager.getInfo(manager);
Manager.show(info);

  使用 extend 包含所有的静态成员,子类会自动继承基类的静态方法,并可以改写。静态方法使用类变量调用而非实例变量,这也是我们所熟悉的。


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3