In JavaScript, a Class Expression is an alternative way to define a class. Much like Function Expressions, Class Expressions can be named or unnamed (anonymous). They provide a powerful way to define classes on the fly, pass them as arguments, or assign them to variables and constants.

The primary difference between a Class Expression and a Class Declaration is hoisting: Class Expressions are not hoisted, meaning you cannot use them before they are defined in your code.

1. Anonymous Class Expressions

In an anonymous expression, the class does not have a name after the class keyword. The variable it is assigned to becomes the identifier for the class.

JavaScript
const Rectangle = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  get area() {
    return this.height * this.width;
  }
};

const instance = new Rectangle(10, 5);
console.log(instance.area); // 50

2. Named Class Expressions

You can provide a name to the class expression. This name is local to the class’s body and is primarily useful for recursion or identifying the class in stack traces during debugging.

JavaScript
const User = class UserEntity {
  constructor(name) {
    this.name = name;
  }
  whoAmI() {
    console.log(UserEntity.name); // Accessing the internal name
  }
};

const me = new User("Gemini");
me.whoAmI(); // "UserEntity"
// console.log(UserEntity); // ReferenceError: UserEntity is not defined

3. Dynamic Class Creation (First-Class Citizens)

Because class expressions are values, they can be used in ways that declarations cannot. This allows for powerful patterns like Higher-Order Classes or Class Factories.

A. Classes as Arguments

You can pass a class expression into a function to be used as a blueprint.

JavaScript
function createInstance(ClassDef, name) {
  return new ClassDef(name);
}

const person = createInstance(class {
  constructor(n) { this.name = n; }
}, "Bob");

B. Class Factories

You can return a class expression from a function. This is often used to generate classes with shared logic based on dynamic input.

JavaScript
function makeClass(phrase) {
  return class {
    sayIt() {
      console.log(phrase);
    }
  };
}

const Greeter = makeClass("Hello World!");
new Greeter().sayIt(); // "Hello World!"

4. Immediately Invoked Class Expressions (IICE)

Similar to IIFEs (Immediately Invoked Function Expressions), you can define a class and instantiate it immediately. This is useful for creating singletons—objects that represent a unique instance of a specific internal logic.

JavaScript
const singleton = new class {
  constructor() {
    this.startTime = Date.now();
  }
  getUptime() {
    return Date.now() - this.startTime;
  }
}();

console.log(singleton.getUptime());

5. Advanced Patterns and Use Cases

A. Higher-Order Functions (Class Factories)

Because class expressions are just “values” (like strings or numbers), you can return them from functions. This is the basis for the Factory Pattern.

JavaScript
function createModel(tableName) {
  return class {
    constructor(data) {
      this.data = data;
    }
    save() {
      console.log(`Saving to ${tableName}...`);
    }
  };
}

const User = createModel('users');
const post = new User({ id: 1 });
post.save(); // "Saving to users..."

B. Immediate Class Instantiation (Singleton-ish)

You can create a class expression and instantiate it immediately. This is useful for creating one-off objects that still require the internal logic/encapsulation of a class.

JavaScript
const appConfig = new (class {
  constructor() {
    this.env = 'production';
  }
  logEnv() {
    console.log(this.env);
  }
})();

appConfig.logEnv(); // "production"

C. Mixins

Class expressions allow you to implement Mixins, which are a way to add functionality to classes without using traditional multiple inheritance (which JavaScript doesn’t support).

JavaScript
const CalculatorMixin = (Base) => class extends Base {
  calc() { return "Calculating..."; }
};

class Machine {}
class Robot extends CalculatorMixin(Machine) {}

const bot = new Robot();
console.log(bot.calc()); // "Calculating..."

Categorized in:

Javascript,