Classes in CoffeeScript

Share this article

Key Takeaways

  • CoffeeScript has implemented a traditional class system, despite JavaScript’s lack of one. This makes it easier for novices to grasp, while still retaining the versatility of prototypes for more experienced coders.
  • CoffeeScript classes support inheritance, allowing for the creation of subclasses that automatically inherit the properties and methods of their parent class. Overriding of parent class functions is also possible in subclasses, as demonstrated with the ‘worry’ and ‘profit’ functions in the ‘Senator’ and ‘Student’ subclasses.
  • Despite its convenience and cleaner syntax, CoffeeScript still allows for the implementation of JavaScript’s prototypical system, including the use of the ‘::’ shortcut for ‘prototype’, and the ‘extends’ and ‘super’ keywords for constructors.
JavaScript doesn’t have a traditional class system. Instead, it has prototypes. Prototypes can be extremely versatile and powerful, but they’re confusing to novices. Hence, CoffeeScript has created a traditional class system. But… how? CoffeeScript’s catchphrase is “It’s Just JavaScript,” and JavaScript is distinctly missing a traditional class system. In this article, we go over the basics of creating a CoffeeScript class. In the next article, we dig into the (relatively advanced) generated JavaScript to figure out how the magic works.

The Parent Class

We’ll do this mostly by example, since it should be fairly easy for those who have read my introductory article on coffeescript to pick up on what’s happening.
class Bourgeoisie
  constructor: (@age, @privilegeConstant) ->

  worry: ->
    console.log("My stocks are down 1%!")

  profit: (hardWork, luck) ->
    return (@age - 23) * hardWork * (luck + @privilegeConstant)

elite = new Bourgeoisie(29, 397)
elite.worry() # "My stocks are down 1%!"
elite.profit(20, 50) #53640
We declare a class called Bourgeoisie. Functions on a class are declared as follows:
functionName: (arguments) ->
  code
The constructor function is named, clearly enough, constructor. It takes two arguments, age and priviligeConstant, and automatically assigns them as instance variables (@ is the CoffeeScript replacement for this, and when used in the argument of a constructor automatically assigns the variable to the instance). The constructor is called automatically when you create a new Bourgeoisie, like at the bottom of the code sample. We also have two other functions. The first, worry, takes no arguments. The second, profit, takes two arguments and returns a number.

The Inherited Class

Now we want to have a class that inherits from Bourgeoisie
. We’ll call it Senator.
class Senator extends Bourgeoisie
  worry: ->
    console.log("The polls are down 1%!")

senator = new Senator(45, 992)
senator.worry() # "The polls are down 1%!")
senator.profit(6, 10) # 132264
This class extends Bourgeoisie, which means that it has all the characteristics of the parent class. The constructor and profit functions are exactly the same, the only difference is that you make a call to Senator instead of Bourgeoisie when constructing an instance. The worry function, on the other hand, is different. The Senator worries about polls more than stocks, so his worry overwrites that of the parent class. This overwriting is seen again in a Student class, shown below.
class Student extends Bourgeoisie
  worry: ->
    console.log("Does my privilege inherently make me complicit in the repression of less fortunate classes?")

  profit: (hardWork, luck, tuition) ->
    super(hardWork, luck) - tuition

student = new Student(21, 89)
student.worry() #"Does my privilege inherently make me complicit in the repression of less fortunate classes?"
student.profit(10, 10, 10000) #-11980
The student’s worry overwrites the parent’s worry
(in an even more dramatic fashion than the Senator’s), and their profit is also overwritten. However, the overwrite is now dependent on the parent class’s profit function. It takes that and subtracts the tuition. It’s a bad time to be a student! But what you should really learn from this is the super keyword, which calls the parent’s version of a function.

But, I Liked Prototypes

Good for you! CoffeeScript gives you convenience, but it still leaves you with power. Let’s use it! Here’s our abbreviated example from last time:
object = (o) ->
    F = ->
    F.prototype = o
    new F()

soldier = new Object()
soldier.a = jump
soldier.r = machineGun

sniper = object(soldier)
sniper.r = snipe

woundedSniper = object(sniper)
woundedSniper.a = -> console.log('aaaargh my leg!')

woundedSoldier = object(soldier)
woundedSoldier.a = woundedSniper.a
This should seem familiar, because 90% of the change was replacing a few function‘s with pointy arrows. The prototypical inheritance system is untouched because, remember, CoffeeScript is just JavaScript. The syntax is cleaner, and there is nothing more to learn if you want to implement prototypes in the Brendan Eich style we used last time. That’s not to say that CoffeeScript doesn’t apply some shortcuts. You can use :: instead of prototype. However, in the Brendan Eich style of prototypes, we only need to use that once, in the object(o) method. We can also access the extends and super keywords, but those are used only in constructors – which we have once again hidden away in the object(o) method.

Conclusion

The classical inheritance system in CoffeeScript provides convenience and comfort to the average developer. In addition, the cleaner syntax of CoffeeScript makes implementing a true prototypal system slightly easier. There’s simply no way to lose.

Frequently Asked Questions about CoffeeScript Classes

What is the significance of classes in CoffeeScript?

Classes in CoffeeScript are a fundamental concept that helps in organizing and structuring the code. They provide a way to create objects with specific properties and methods. Classes make it easier to create complex data structures and provide a way to encapsulate data and functionality in one place. They also support inheritance, which allows you to create a new class that inherits properties and methods from an existing class. This can greatly reduce code duplication and improve code maintainability.

How do I define a class in CoffeeScript?

Defining a class in CoffeeScript is straightforward. You use the class keyword followed by the name of the class. For example, class MyClass. You can then define properties and methods within the class using the @ symbol to refer to the instance of the class. For example, @myProperty would define a property on the class, and @myMethod: -> would define a method.

How does inheritance work in CoffeeScript classes?

Inheritance in CoffeeScript is achieved using the extends keyword. When you define a class, you can specify that it extends another class. This means that the new class will inherit all the properties and methods of the class it extends. For example, class MySubClass extends MyClass would create a new class that inherits from MyClass.

Can I override methods in a subclass in CoffeeScript?

Yes, you can override methods in a subclass in CoffeeScript. When you define a method in a subclass with the same name as a method in the superclass, the subclass’s method will be used instead. If you still want to call the superclass’s method, you can do so using the super keyword.

How do I create an instance of a class in CoffeeScript?

To create an instance of a class in CoffeeScript, you use the new keyword followed by the name of the class. For example, myInstance = new MyClass would create a new instance of MyClass.

What is the purpose of the constructor method in CoffeeScript classes?

The constructor method in CoffeeScript classes is a special method that gets called when a new instance of the class is created. It’s typically used to initialize the properties of the class. In CoffeeScript, the constructor method is defined using the constructor keyword.

Can I define private properties and methods in CoffeeScript classes?

CoffeeScript does not have built-in support for private properties and methods. However, you can achieve a similar effect by using closures or by defining properties and methods within the constructor method, which makes them only accessible within the instance of the class.

How do I call a method on a class instance in CoffeeScript?

To call a method on a class instance in CoffeeScript, you use the . operator followed by the name of the method. For example, myInstance.myMethod() would call the myMethod method on the myInstance object.

Can I add properties and methods to a class after it’s been defined in CoffeeScript?

Yes, you can add properties and methods to a class after it’s been defined in CoffeeScript. You can do this by defining them on the prototype of the class. For example, MyClass::myNewMethod = -> would add a new method to MyClass.

How do I check the type of a class instance in CoffeeScript?

To check the type of a class instance in CoffeeScript, you can use the instanceof operator. For example, myInstance instanceof MyClass would return true if myInstance is an instance of MyClass.

Jeffrey BilesJeffrey Biles
View Author
Intermediate
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week