13. Classes
Calling a class without `new` throws a TypeError.
What you'll learn
- 1Define object blueprints with `class` syntax.
- 2Use a `constructor` to initialize an instance.
- 3Implement inheritance with `extends` and `super`.
- 4Use `static` methods and getter/setter pairs.
- 5Understand that classes are syntactic sugar over prototypes.
Overview
Calling a class without `new` throws a TypeError.
Core Concepts
1. Class basics
class Person {
constructor(name) {
this.name = name;
}
hello() {
return `Hi, I am ${this.name}`;
}
}
const p = new Person("Sun");
p.hello();Calling a class without `new` throws a TypeError.
2. Inheritance (extends, super)
class Student extends Person {
constructor(name, grade) {
super(name);
this.grade = grade;
}
intro() {
return `${super.hello()} (grade ${this.grade})`;
}
}`super(...)` calls the parent constructor; `super.method()` calls a parent method.
3. static and getter/setter
Static members live on the class itself rather than on instances.
class MathX {
static square(x) { return x * x; }
}
MathX.square(5);
class Temp {
constructor(c) { this._c = c; }
get fahrenheit() { return this._c * 9/5 + 32; }
set fahrenheit(f) { this._c = (f - 32) * 5/9; }
}4. Relationship to prototypes
`class` is internally implemented with functions and the prototype chain. `Person.prototype.hello === p.hello`.
Examples
| File | What it covers |
|---|---|
| `01_class_basic.js` | Class basics |
| `02_constructor.js` | Constructor and instance fields |
| `03_extends.js` | Inheritance and super |
| `04_static_getter.js` | static, getter/setter |
src/01_class_basic.js
/**
* Class basics
*/
"use strict";
class Person {
constructor(name) {
this.name = name;
}
hello() {
return `Hi, I am ${this.name}`;
}
}
const p = new Person("Yuna");
console.log(p.hello());
console.log(p instanceof Person);
src/02_constructor.js
/**
* Constructor and instance fields
*/
"use strict";
class Book {
// Class field
likes = 0;
constructor(title, author) {
this.title = title;
this.author = author;
}
like() {
this.likes += 1;
}
}
const b = new Book("JS", "Kim");
b.like();
b.like();
console.log(b);
src/03_extends.js
/**
* Inheritance and super
*/
"use strict";
class Animal {
constructor(name) { this.name = name; }
speak() { return `${this.name} makes a sound`; }
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
speak() {
return `${super.speak()} (woof, ${this.breed})`;
}
}
const d = new Dog("Rex", "Husky");
console.log(d.speak());
console.log(d instanceof Animal); // true
src/04_static_getter.js
/**
* static and getter/setter
*/
"use strict";
class MathX {
static square(x) { return x * x; }
}
console.log(MathX.square(6));
class Temp {
constructor(c) { this._c = c; }
get fahrenheit() { return this._c * 9 / 5 + 32; }
set fahrenheit(f) { this._c = (f - 32) * 5 / 9; }
get celsius() { return this._c; }
}
const t = new Temp(0);
console.log("F =", t.fahrenheit); // 32
t.fahrenheit = 212;
console.log("C =", t.celsius); // 100
Common Mistakes
- Calling a class without `new` → TypeError.
- Accessing `this` in a child constructor before calling `super()`.
- Defining methods as arrow functions, creating a new closure per instance (memory waste).
- Thinking `this` in a `static` method refers to an instance (it refers to the class).
- Trying to define both a getter/setter and a plain property of the same name.
FAQ
Q1. How do I create private fields?
Use the `#field` syntax (ES2022+) for truly private fields.
Q2. Does JavaScript support multiple inheritance?
No — use mixins as a workaround.
Q3. Class or factory function?
Classes are strong on `new`/inheritance; factories make private state via closures easier.
Practice
- `homework_01.js` — Write `Animal` and `Dog extends Animal`.
- `homework_02.js` — Add an `area` getter and a static `from` method to `Rectangle`.
homework/README.md
## homework_01.js
- `Animal` class: a `name` field and a `speak()` method that returns `"<name> speaks"`
- `Dog` class: extends `Animal`, overrides `speak()` to return `"<name> barks"`
## homework_02.js — Write a `Rectangle` class.
- Fields: `width`, `height`
- Getter `area` → the area
- Static `from(side)` → returns a Rectangle representing a square of the given side
homework/answer/homework_01.js
/**
* Homework 1: Animal / Dog
*/
"use strict";
class Animal {
constructor(name) { this.name = name; }
speak() { return `${this.name} speaks`; }
}
class Dog extends Animal {
speak() { return `${this.name} barks`; }
}
console.log(new Animal("Cat").speak());
console.log(new Dog("Rex").speak());
homework/answer/homework_02.js
/**
* Homework 2: Rectangle
*/
"use strict";
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
get area() {
return this.width * this.height;
}
static from(side) {
return new Rectangle(side, side);
}
}
const r = new Rectangle(4, 5);
console.log("area =", r.area);
const sq = Rectangle.from(7);
console.log("sq area =", sq.area);
Next Lecture
[14_Callbacks_and_Timers](../../04_비동기/14_콜백과_타이머/) — Async intro.
All lecture materials and example code are openly available on GitHub.
View on GitHub ↗