Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 7.8 — Composition over Inheritance
JavaScript · Example 4 of 4

When a class is overkill

The destructured increment still works because it uses a closure, not this. Object.assign copies mixin methods as enumerable keys, unlike real class methods.

Instead of building tall family trees of classes, build objects from small parts: an object has an engine rather than is an engine, borrows abilities through mixins, or hands work to a helper (delegation); and when there is no shared behaviour to organise, a plain object and a few functions beat a class.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 5 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Write factories withName(name) and withGreeting(state) and combine them into createPerson("Asha") so that person.greet() returns "Hello, I am Asha", without class or this.

02

Write a class Logger that has a writer (any object with write(text)), and a method info(msg) that calls writer.write("[info] " + msg). Use a writer that pushes into an array, and print the array after two calls.

03

Write a subclass-factory mixin WithCount that adds a count field and an increment() method, apply it to an empty class Base {}, and show two instances counting separately.

Explain it without notes

01

What does "favour composition over inheritance" mean, and why is it good advice?

02

What is delegation, and how does duck typing make it flexible?

03

What are mixins in JavaScript? Compare Object.assign mixins with subclass factories.

04

When is a class overkill, and when is it the right tool?

When a class is overkill

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

dark Rs 5.00 12
count is hidden: [ 'increment', 'value' ]
{"x":1,"y":2} [ 'toText' ]