Execute Program

Modern JavaScript: Anonymous and Inline Classes

Welcome to the Anonymous and Inline Classes lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • We've seen that functions have a name property.

  • >
    function one() { return 1; }
    one.name;
    Result:
    'one'Pass Icon
  • Classes also have a name property.

  • >
    class Cat { }
    Cat.name;
    Result:
    'Cat'Pass Icon
  • Just as with functions, the class definition itself can be assigned to a variable. Many object-oriented programming languages don't allow this, but JavaScript does allow it.

  • >
    const Animal = class Cat {
    speak() {
    return 'nyan';
    }
    };
    new Animal().speak();
    Result:
    'nyan'Pass Icon
  • We can even inline the class definition into the new expression, so it's never assigned to a variable at all:

  • >
    const cat = new (
    class {
    speak() {
    return 'yaong';
    }
    }
    )();
    cat.speak();
    Result:
    'yaong'Pass Icon
  • When we try to inspect the name of an anonymous class, we'll get the empty string ('').

  • >
    (
    class { }
    ).name;
    Result:
    ''Pass Icon
  • If we immediately assign the class to a variable, that variable's name will become the class' name. This is the same behavior that we saw with anonymous functions.

  • >
    const Cat = class { };
    Cat.name;
    Result:
    'Cat'Pass Icon
  • As with functions, the anonymous class' name will be '' if it's not assigned to variable directly. In the next example, note that the classes variable is an array, which contains a single class. The class isn't directly assigned to a variable, so it gets no name.

  • >
    const classes = [class { }];
    classes[0].name;
    Result:
    ''Pass Icon
  • Here's a code problem:

    Define an anonymous rectangle class inside the array. Its constructor should take width and height arguments. It should have an area method that returns the rectangle's area (the width times the height). We've provided the code to instantiate your class anonymously by storing it inside an array, then newing it from inside that array.

    const classes = [
    class {
    constructor(width, height) {
    this.width = width;
    this.height = height;
    }
    area() {
    return this.width * this.height;
    }
    }
    ];
    const Rectangle = classes[0];
    const rectangle = new Rectangle(3, 4);
    [rectangle.area(), classes[0].name];
    Goal:
    [12, '']
    Yours:
    [12, '']Pass Icon
  • Inheritance works as usual, even when both classes are anonymous. An anonymous class can extend another anonymous class!

  • >
    const Animal = class { };
    const Cat = class extends Animal { };
    new Cat() instanceof Animal;
    Result:
    truePass Icon
  • >
    const classes = [];
    classes.push(class { });
    classes.push(class extends classes[0] { });
    const ParentClass = classes[0];
    const ChildClass = classes[1];
    new ChildClass() instanceof ParentClass;
    Result:
    truePass Icon
  • In this lesson, we've seen classes and functions behave similarly with regards to the name property. Here's why they're so similar:

  • >
    typeof (class Cat { });
    Result:
  • Internally, JavaScript classes are just functions. The implications of that are complex and, to be honest about it, pretty confusing. But we just saw one implication: when we assign an anonymous class directly to a variable, that variable's name becomes the class' name. That's not because classes and functions follow the same rule; it's because classes are functions!

  • Classes can be anonymous (have no name), and they can be inline (the class definition itself is used as an expression). Both of those are uncommon. Because inline and anonymous classes can be complex and confusing, we recommend avoiding them when possible. But they are used in real systems, so you'll encounter them eventually!