Classes as First-Class Citizens

In programming, something is said to be a first-class citizen when it can be used as a value, meaning it can be passed into a function, returned from a function, and assigned to a variable. JavaScript functions are first-class citizens (sometimes they’re just called first class functions), and that’s part of what makes JavaScript unique.

ECMAScript 6 continues this tradition by making classes first-class citizens as well. That allows classes to be used in a lot of different ways. For example, they can be passed into functions as arguments:

  1. function createObject(classDef) {
  2. return new classDef();
  3. }
  4. let obj = createObject(class {
  5. sayHi() {
  6. console.log("Hi!");
  7. }
  8. });
  9. obj.sayHi(); // "Hi!"

In this example, the createObject() function is called with an anonymous class expression as an argument, creates an instance of that class with new, and returns the instance. The variable obj then stores the returned instance.

Another interesting use of class expressions is creating singletons by immediately invoking the class constructor. To do so, you must use new with a class expression and include parentheses at the end. For example:

  1. let person = new class {
  2. constructor(name) {
  3. this.name = name;
  4. }
  5. sayName() {
  6. console.log(this.name);
  7. }
  8. }("Nicholas");
  9. person.sayName(); // "Nicholas"

Here, an anonymous class expression is created and then executed immediately. This pattern allows you to use the class syntax for creating singletons without leaving a class reference available for inspection. (Remember that PersonClass only creates a binding inside of the class, not outside.) The parentheses at the end of the class expression are the indicator that you’re calling a function while also allowing you to pass in an argument.

The examples in this chapter so far have focused on classes with methods. But you can also create accessor properties on classes using a syntax similar to object literals.