← Back to JavaScript series
🏛️
Functional · ES6
Intermediate · Prerequisite: 12_Closures_and_Scope

13. Classes

Calling a class without `new` throws a TypeError.

classinheritancesuperextends
Duration
~1.5 hours
Level
📊 Intermediate
Prerequisite
🎯 Lecture 12
OUTCOME
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

javascript
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)

javascript
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.

javascript
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

FileWhat 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

javascript
/**
 * 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

javascript
/**
 * 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

javascript
/**
 * 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

javascript
/**
 * 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

  1. Calling a class without `new` → TypeError.
  2. Accessing `this` in a child constructor before calling `super()`.
  3. Defining methods as arrow functions, creating a new closure per instance (memory waste).
  4. Thinking `this` in a `static` method refers to an instance (it refers to the class).
  5. 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

javascript
/**
 * 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

javascript
/**
 * 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.

Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub ↗