Coffeescript 简明教程

CoffeeScript - Classes and Inheritance

JavaScript不提供 class 关键字。我们可以使用对象及其原型在JavaScript中实现继承。每个对象都有自己的原型,并且它们从其原型中继承函数和属性。由于原型也是一个对象,因此它也有自己的原型。

尽管原型继承比经典继承强大得多,但对于新手用户来说,它却很困难且容易混淆。

Classes in CoffeeScript

为了解决此问题,CoffeeScript提供了一种称为 class 的基本结构,它是使用JavaScript的原型构建的。您可以使用class关键字在CoffeeScript中定义一个类,如下所示。

class Class_Name

Example

考虑以下示例,在这里,我们使用关键字 class 创建了一个名为 Student 的类。

class Student

如果您编译上面的代码,它将生成以下JavaScript。

var Student;

Student = (function() {
  function Student() {}

  return Student;

})();

Instantiating a class

我们可以使用new运算符实例化一个类,就像其他面向对象编程语言一样,如下所示。

new Class_Name

您可以使用 new 运算符实例化上述创建的(Student)类,如下所示。

class Student
new  Student

如果您编译上面的代码,它将生成以下JavaScript。

var Student;

Student = (function() {
  function Student() {}

  return Student;

})();

new Student;

Defining a Constructor

构造函数是一个在实例化类时调用的函数,它的主要目的是初始化实例变量。在CoffeeScript中,您可以通过创建一个名为 constructor 的函数来定义一个构造函数,如下所示。

class Student
  constructor: (name)->
  @name = name

在这里,我们定义了一个构造函数并将局部变量名称分配给实例变量。

@ 运算符是 this 关键字的别名,它用于指向类的实例变量。

如果我们在构造函数的参数前面放置 @ ,它将自动设置为实例变量。因此,上面的代码可以简单地写成如下所示:

class Student
  constructor: (@name)->

Example

这是一个CoffeeScript中的构造函数示例。将其另存为名为 constructor_example.coffee 的文件中

#Defining a class
class Student
  constructor: (@name)->

#instantiating a class by passing a string to constructor
student = new Student("Mohammed");
console.log "the name of the student is :"+student.name

Compiling the code

打开命令提示符并编译上述示例,如下所示。

c:\>coffee -c constructor_example.coffee

执行上述命令将生成以下JavaScript。

// Generated by CoffeeScript 1.10.0
(function() {
  var Student, student;

  Student = (function() {
    function Student(name) {
      this.name = name;
    }

    return Student;

  })();

  student = new Student("Mohammed");

  console.log("The name of the student is :"+student.name);

}).call(this);

Executing the Code

在命令提示符上执行以下命令,以运行上述示例。

coffee constructor_example.coffee

运行后,上述示例将给出以下输出。

The name of the student is :Mohammed

Instance Properties

与对象中一样,我们还可以在类中使用属性。这些称作 instance properties

Example

考虑以下示例。在该示例中,我们在类中创建了变量(name、age)和函数(message()),并使用该对象访问了它们。将此示例保存为名为 instance_properties_example.coffee 的文件。

#Defining a class
class Student
  name="Ravi"
  age=24
  message: ->
    "Hello "+name+" how are you"

#instantiating a class by passing a string to constructor
student = new Student();
console.log student.message()

在编译后,上述代码将生成以下输出。

// Generated by CoffeeScript 1.10.0
(function() {
  var Student, student;

  Student = (function() {
    var age, name;

    function Student() {}

    name = "Ravi";

    age = 24;

    Student.prototype.message = function() {
      return "Hello " + name + " how are you";
    };

    return Student;

  })();

  student = new Student();

  console.log(student.message());

}).call(this);

Static Properties

我们可以在类中定义静态属性。静态属性的范围局限在类中,我们使用 this keyword 或其别名 @ 符号创建静态函数,并且我们必须通过类名称 Class_Name.property 访问这些属性。

Example

以下示例中,我们创建了一个名为 message 的静态函数,并对它进行了访问。将其保存在名为 static_properties_example.coffee 的文件中。

#Defining a class
class Student
  @message:(name) ->
    "Hello "+name+" how are you"
console.log Student.message("Raju")

使用以下命令打开命令提示符并编译上面的 CoffeeScript 文件。

c:\>coffee -c  static_properties_example.coffee

编译后,它会给你以下 JavaScript。

// Generated by CoffeeScript 1.10.0
(function() {
  var Student;

  Student = (function() {
    function Student() {}

    Student.message = function(name) {
      return "Hello " + name + " how are you";
    };

    return Student;

  })();

  console.log(Student.message("Raju"));

}).call(this);

在命令提示符中执行上面的 coffeeScript,如下所示。

c:\>coffee static_properties_example.coffee

执行时,上面的示例将输出以下内容。

Hello Raju how are you

Inheritance

在 CoffeeScript 中,我们可以使用 extends 关键字从一个类继承另一个类的属性。

Example

以下是 CoffeeScript 中继承的一个示例。在这里,我们有两个类,即 AddMy_class 。我们继承了名为 Add 的类的属性在 My_class 类中,并使用 extends 关键字访问它们。

#Defining a class
class Add
   a=20;b=30

   addition:->
     console.log "Sum of the two numbers is :"+(a+b)

class My_class extends Add

my_class = new My_class()
my_class.addition()

CoffeeScript 幕后使用原型继承。在 CoffeeScript 中,每当我们创建实例时,都会调用父类的构造函数,直到我们重写它。

我们可以使用 super() 关键字从子类调用父类的构造函数,如下面的示例所示。

#Defining a class
class Add
   constructor:(@a,@b) ->

   addition:=>
     console.log "Sum of the two numbers is :"+(@a+@b)

class Mul extends Add
   constructor:(@a,@b) ->
     super(@a,@b)

   multiplication:->
     console.log "Product of the two numbers is :"+(@a*@b)

mul = new Mul(10,20)
mul.addition()
mul.multiplication()

Dynamic Classes

CoffeeScript 使用原型继承自动继承类的所有实例属性。这确保了类的动态性;即使在创建子类之后向父类添加属性,该属性仍会传播到所有继承的子类。

class Animal
  constructor: (@name) ->

class Parrot extends Animal

Animal::rip = true

parrot = new Parrot("Macaw")
console.log "This parrot is no more" if parrot.rip

执行时,上面的 CoffeeScript 生成以下 JavaScript 代码。

// Generated by CoffeeScript 1.10.0
(function() {
  var Animal, Parrot, parrot,
    extend = function(child, parent) { for (var key in parent) {
      if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() {
      this.constructor = child; } ctor.prototype = parent.prototype;
      child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Animal = (function() {
    function Animal(name) {
      this.name = name;
    }

    return Animal;

  })();

  Parrot = (function(superClass) {
    extend(Parrot, superClass);

    function Parrot() {
      return Parrot.__super__.constructor.apply(this, arguments);
    }

    return Parrot;

  })(Animal);

  Animal.prototype.rip = true;

  parrot = new Parrot("Macaw");

  if (parrot.rip) {
    console.log("This parrot is no more");
  }

}).call(this);