JavaScript course menu
JavaScript Classes: Constructors, Methods, Getters, Static and Private Fields
Learn JavaScript classes: defining a class, the constructor, instance properties and methods, class fields, getters and setters, static methods and properties, private #fields and methods, instanceof, and when to use classes.
On this page
A class is a blueprint for creating objects that share the same structure and behaviour. If your program has many users, products or bank accounts, a class describes them once, and you create as many instances as you need.
Defining a class#
class Student {
constructor(name, course) {
this.name = name;
this.course = course;
this.completed = 0;
}
completeLesson() {
this.completed++;
return this;
}
describe() {
return `${this.name} has completed ${this.completed} ${this.course} lessons`;
}
}
const asha = new Student("Asha", "JavaScript");
const ravi = new Student("Ravi", "CSS");
asha.completeLesson().completeLesson();
ravi.completeLesson();
console.log(asha.describe());
console.log(ravi.describe());
console.log(asha instanceof Student);Asha has completed 2 JavaScript lessons
Ravi has completed 1 CSS lessons
trueclass Student { ... }defines the class. Class names usePascalCase.constructorruns when you callnew Student(...); it sets up the new object's properties throughthis.- Methods such as
describe()are shared by every instance. newcreates the instance. Calling a class withoutnewis an error.- Returning
thisfrom a method allows chaining, as inasha.completeLesson().completeLesson().
Class fields#
Properties can be declared directly in the class body, which makes the shape of the object easy to see:
class Cart {
items = [];
currency = "₹";
add(name, price) {
this.items.push({ name, price });
}
total() {
return this.items.reduce((sum, item) => sum + item.price, 0);
}
}
const cart = new Cart();
cart.add("Pen", 20);
cart.add("Notebook", 60);
console.log(`${cart.currency}${cart.total()}`);₹80Each instance gets its own items array.
Getters and setters#
A getter is a method you read like a property; a setter runs when the property is assigned, which is useful for validation:
class Temperature {
#celsius = 0;
get fahrenheit() {
return this.#celsius * 9 / 5 + 32;
}
get celsius() {
return this.#celsius;
}
set celsius(value) {
if (value < -273.15) throw new RangeError("Below absolute zero");
this.#celsius = value;
}
}
const t = new Temperature();
t.celsius = 30;
console.log(t.celsius, t.fahrenheit);
try {
t.celsius = -500;
} catch (error) {
console.log(error.message);
}30 86
Below absolute zeroPrivate fields and methods#
Names starting with # are private: they can only be used inside the class. Code outside cannot read or change them, which protects the object's rules:
class BankAccount {
#balance = 0;
deposit(amount) {
this.#validate(amount);
this.#balance += amount;
}
withdraw(amount) {
this.#validate(amount);
if (amount > this.#balance) throw new Error("Insufficient funds");
this.#balance -= amount;
}
get balance() {
return this.#balance;
}
#validate(amount) {
if (amount <= 0) throw new RangeError("Amount must be positive");
}
}
const account = new BankAccount();
account.deposit(500);
account.withdraw(200);
console.log(account.balance);
console.log(account.balanceTypo);
console.log(Object.keys(account));300
undefined
[]Trying to write account.#balance outside the class is a syntax error, so it cannot even run. Private fields are truly hidden, unlike the old convention of naming "private" properties with an underscore.
Static members#
static methods and properties belong to the class itself, not to instances. They suit helpers and factory functions:
class Temperature {
static fromFahrenheit(f) {
return Math.round(((f - 32) * 5) / 9);
}
static ABSOLUTE_ZERO = -273.15;
}
console.log(Temperature.fromFahrenheit(98.6));
console.log(Temperature.ABSOLUTE_ZERO);37
-273.15You call them on the class (Temperature.fromFahrenheit), not on an instance. Math.max and Number.isNaN are built-in static methods.
Classes are functions underneath#
JavaScript classes are a clearer syntax over the language's prototypes: methods live on Student.prototype and are shared by all instances. typeof Student is "function". The Prototypes lesson shows how this works.
When to use classes#
Classes are a good fit when you have many objects with the same behaviour and internal state to protect: shopping carts, game entities, custom errors (Error Handling), or when a library or framework expects them. For simple data, plain objects and functions are often enough. Both styles are common in JavaScript.
Practice#
Practice exercise
Create a Rectangle class with width and height, a getter area, a method scale(factor) that returns a new rectangle, and a static method square(size). Test them.
Show solution
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
get area() {
return this.width * this.height;
}
scale(factor) {
return new Rectangle(this.width * factor, this.height * factor);
}
static square(size) {
return new Rectangle(size, size);
}
}
const r = new Rectangle(3, 4);
console.log(r.area);
console.log(r.scale(2).area);
console.log(Rectangle.square(5).area);
console.log(r.area);12
48
25
12scale returns a new rectangle, so r itself is unchanged.
Key takeaway#
Finished this lesson?