Skip to content

Intermediate · Scope, this, prototypes and classes · topic 24 of 61 · 30 min

Classes

Explanation

A class is a template for making objects that share the same shape and methods. The constructor sets up each new object, methods are shared on the prototype, #private fields hide data, static members belong to the class itself, and get/set create computed properties. Classes are a cleaner syntax over prototypes, not a new system.

Why classes?

When you need many objects of the same kind, like bank accounts, each with data (owner, balance) and behaviour (deposit, withdraw), a class keeps the data and the functions that work on it together. This style is called object-oriented programming (OOP). ES2015 classes are syntax over the prototype system you just learned: methods still end up on ClassName.prototype.

javascript
class BankAccount {
  constructor(owner, balance = 0) {
    this.owner = owner;
    this.balance = balance;
  }
  deposit(amount) {
    this.balance += amount;
    return this.balance;
  }
}
const acc = new BankAccount('Asha', 1000);
console.log(acc.deposit(500));       // 1500
console.log(typeof BankAccount);     // 'function' (a class is a special function)

An object made from a class is an instance. new runs the constructor with this set to the new instance. Calling a class without new throws a TypeError.

Fields and private fields

Class fields declare properties right in the class body. A field whose name starts with # is private: it can only be read or written by code inside the class. Trying to reach acc.#balance from outside is a SyntaxError, so nobody can set the balance to a million by mistake.

javascript
class Wallet {
  #balance = 0;          // private field
  currency = 'INR';      // public field
  pay(amount) {
    if (amount > this.#balance) throw new Error('Insufficient balance');
    this.#balance -= amount;
  }
  topUp(amount) { this.#balance += amount; }
  get balance() { return this.#balance; }   // read-only from outside
  #log(msg) { /* private method */ }
}
const w = new Wallet();
w.topUp(300);
w.pay(120);
console.log(w.balance);   // 180
w.balance = 1000000;      // no setter: ignored (TypeError in strict code)
console.log(w.balance);   // 180

Getters and setters

get name() runs a function when you READ obj.name; set name(v) runs when you ASSIGN to it. They let you compute values or validate input while keeping the simple property syntax.

javascript
class Temperature {
  #celsius = 0;
  get fahrenheit() { return this.#celsius * 9 / 5 + 32; }
  set celsius(value) {
    if (value < -273.15) throw new RangeError('Below absolute zero');
    this.#celsius = value;
  }
}
const t = new Temperature();
t.celsius = 37;
console.log(t.fahrenheit); // 98.6

Static members

static methods and fields belong to the class itself, not to instances. Use them for helpers and factories that do not need a particular object.

javascript
class Money {
  static GST_RATE = 18;
  static fromRupees(r) { return new Money(Math.round(r * 100)); }
  constructor(paise) { this.paise = paise; }
}
console.log(Money.GST_RATE);                 // 18
console.log(Money.fromRupees(12.5).paise);   // 1250

instanceof

obj instanceof Class checks whether Class.prototype is in obj's prototype chain: acc instanceof BankAccount is true.

Careful: Methods are not automatically bound. const d = acc.deposit; d(10) loses this and throws. Pass methods as callbacks with an arrow, () => acc.deposit(10), or define the method as an arrow class field (deposit = (amount) => {…}), which binds it to each instance at the cost of one function per object.
Tip: Keep classes small with one clear job. Prefer #private fields for anything that must stay valid (like a balance) and expose behaviour through methods.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Classes · 1/6

Classes

In this lesson you will write classes, templates for making many similar objects.

Prefer a video by a teacher? Find free videos on “javascript classes private fields getters setters static” on YouTube ↗

In real life: An inventory item in a warehouse app

A warehouse system models each stock item as a class. The quantity is private, so it can only change through receive and dispatch, which refuse to let stock go below zero. Reports read the value through a getter.

javascript
class StockItem {
  #qty = 0;
  constructor(sku, price) { this.sku = sku; this.price = price; }
  receive(n) { this.#qty += n; }
  dispatch(n) {
    if (n > this.#qty) return false;
    this.#qty -= n;
    return true;
  }
  get value() { return this.#qty * this.price; }
}
const item = new StockItem('BOTTLE-1L', 250);
item.receive(40);
item.dispatch(15);
console.log(item.value); // 6250

Practice (0/3 done)

Task 1 · Code · Javascript

Write a class Rectangle with a constructor(width, height) and a method area() returning width * height.

Task 2 · Code · Javascript

Write a class Counter with a PRIVATE field #count starting at 0, methods increment() and reset(), and a getter value. increment returns the new value.

Task 3 · Code · Javascript

Write a class Temperature with a setter celsius that throws a RangeError for values below -273.15, and a getter fahrenheit (C × 9/5 + 32).

Quick quiz

Question 1

1.Where do the methods of a class live?

Question 2

2.What happens when you call a class without new?

Question 3

3.How is a static method called?

Question 4

4.What makes a class field private?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Where do the methods of a class live?

Answer: On ClassName.prototype

Class methods are put on the prototype and shared.

What happens when you call a class without new?

Answer: TypeError

Class constructors cannot be invoked without new.

How is a static method called?

Answer: ClassName.method()

Static members belong to the class itself.

What makes a class field private?

Answer: A leading #

#name fields are truly private; _name is only a naming convention.

Why put methods on F.prototype rather than inside the constructor?Related

Answer: All instances share one copy, saving memory

Methods created inside the constructor are copied for each object.

From Prototypes and the prototype chain

The JavaBeans getter name for a boolean field active is…Related

Answer: isActive()

Boolean getters conventionally start with is.

From Encapsulation: private fields, getters and setters

Two objects of the same class…Related

Answer: Each have their own copies of instance fields

Instance fields belong to each object.

From Classes and objects

How do you make a field private in Dart?Related

Answer: Start its name with _

Underscore names are library-private.

From Classes and constructors

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 1 more topic in “Scope, this, prototypes and classes” before its exam: Inheritance and composition.
  2. Module 5 exam: Scope, this, prototypes and classes · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Modules, errors, JSON and dates. 61 topics left in the course before the final exam.

← Previous: Prototypes and the prototype chain