JavaScript Curriculum
Blueprints for Objects
mediumThe Nexus backend models users with plain objects — { name, role, xp }. But the codebase has grown: promoting a user, checking permissions, formatting their display name — that logic is scattered across dozens of files. Classes collect data and behaviour together. One User class, one place for all user logic, one blueprint that every part of the system can trust.
Classes are blueprints
A class defines the shape and behaviour of objects. You write the blueprint once, then create as many instances as you need — each with its own data, all sharing the same methods.
new User() runs the constructor, allocates a fresh object, and returns it. this inside the class always refers to that specific instance.
Click any part of the class to understand what it does:
Click a coloured line to learn about that part of the class.
Class fields — declaring properties at the top
Modern JavaScript lets you declare instance properties at the class body level, not only inside the constructor:
Private fields with # are truly private — enforced by the JavaScript engine, not just convention. They don't appear in Object.keys(), JSON.stringify(), or the console.
Getters and setters
Getters let you expose computed values as if they were plain properties:
Use getters for derived values that should stay in sync with underlying data. Use setters to add validation when a property is assigned.
Static methods and properties
Static members belong to the class itself, not to instances:
Factory methods (User.create()), utility functions, and constants that belong to the concept but not to any specific instance are the primary uses of static.
Inheritance — extends and super
One class can extend another, inheriting all its properties and methods:
base class
derived class
User is the base class. It defines name, role, xp, greet(), and promote().
Key rules:
super(args)must be called in the derived constructor before you accessthis- Derived classes inherit all public methods and fields from the base
- Private fields (
#) are not inherited — they're invisible to subclasses - You can override an inherited method by defining it again in the subclass
Method overriding
super.method() calls the parent class's version of a method. Use it when you want to extend rather than replace the parent behaviour.
Classes vs plain objects
Classes aren't mandatory. Plain objects and functions can do everything classes do. Use classes when:
- Multiple instances share methods (classes put methods on the prototype — one copy for all instances)
- You need inheritance (
extends) - You want private state (
#privateField) - The codebase already uses class conventions (React class components, most backend frameworks)
For simple data containers, plain objects are often cleaner. For entities with behaviour that many parts of the codebase interact with, classes give you a clear, well-understood structure.
Challenge
Define a class called Animal with a constructor that takes name and sound. Add a method speak() that returns name + ' says ' + sound + '!'. Add a static method describe() that returns 'Animals communicate through sound.'. Then define a class Dog that extends Animal. Dog's constructor takes only name and calls super with name and 'woof'. Add a method fetch(item) that returns name + ' fetches the ' + item + '!'. Create a Dog instance called rex with name 'Rex' and test all methods.
Blueprints for Objects
mediumThe Nexus backend models users with plain objects — { name, role, xp }. But the codebase has grown: promoting a user, checking permissions, formatting their display name — that logic is scattered across dozens of files. Classes collect data and behaviour together. One User class, one place for all user logic, one blueprint that every part of the system can trust.
Classes are blueprints
A class defines the shape and behaviour of objects. You write the blueprint once, then create as many instances as you need — each with its own data, all sharing the same methods.
new User() runs the constructor, allocates a fresh object, and returns it. this inside the class always refers to that specific instance.
Click any part of the class to understand what it does:
Click a coloured line to learn about that part of the class.
Class fields — declaring properties at the top
Modern JavaScript lets you declare instance properties at the class body level, not only inside the constructor:
Private fields with # are truly private — enforced by the JavaScript engine, not just convention. They don't appear in Object.keys(), JSON.stringify(), or the console.
Getters and setters
Getters let you expose computed values as if they were plain properties:
Use getters for derived values that should stay in sync with underlying data. Use setters to add validation when a property is assigned.
Static methods and properties
Static members belong to the class itself, not to instances:
Factory methods (User.create()), utility functions, and constants that belong to the concept but not to any specific instance are the primary uses of static.
Inheritance — extends and super
One class can extend another, inheriting all its properties and methods:
base class
derived class
User is the base class. It defines name, role, xp, greet(), and promote().
Key rules:
super(args)must be called in the derived constructor before you accessthis- Derived classes inherit all public methods and fields from the base
- Private fields (
#) are not inherited — they're invisible to subclasses - You can override an inherited method by defining it again in the subclass
Method overriding
super.method() calls the parent class's version of a method. Use it when you want to extend rather than replace the parent behaviour.
Classes vs plain objects
Classes aren't mandatory. Plain objects and functions can do everything classes do. Use classes when:
- Multiple instances share methods (classes put methods on the prototype — one copy for all instances)
- You need inheritance (
extends) - You want private state (
#privateField) - The codebase already uses class conventions (React class components, most backend frameworks)
For simple data containers, plain objects are often cleaner. For entities with behaviour that many parts of the codebase interact with, classes give you a clear, well-understood structure.
Challenge
Define a class called Animal with a constructor that takes name and sound. Add a method speak() that returns name + ' says ' + sound + '!'. Add a static method describe() that returns 'Animals communicate through sound.'. Then define a class Dog that extends Animal. Dog's constructor takes only name and calls super with name and 'woof'. Add a method fetch(item) that returns name + ' fetches the ' + item + '!'. Create a Dog instance called rex with name 'Rex' and test all methods.