JS

JavaScript Fundamentals

25 lessons

Progress0%
1. Introduction to JavaScript
1What is JavaScript?2Setting Up Your Environment
2. Variables and Data Types
1Declaring Variables2Data Types3Type Conversion
3. Operators
Arithmetic OperatorsComparison OperatorsLogical Operators
4. Control Flow
Conditional StatementsLoops
5. Functions
Function Basics
6. Arrays & Iteration
Array MethodsSpread, Rest & Destructuring
7. Objects & JSON
Working with ObjectsJSON & Optional Chaining
8. OOP & Classes
Class BasicsInheritance & Private Fields
9. Modules & Modern JS
ES ModulesModern JavaScript Features
10. Async JavaScript
PromisesAsync/Await
11. Error Handling
Error Types & try/catchCustom Errors & Debugging
12. Iterators & Advanced
Iterators & GeneratorsMap, Set & WeakRefs
All Tutorials
JavaScriptOOP & Classes
Lesson 16 of 25 min
Chapter 8 · Lesson 1

Class Basics

Class Basics

ES2015 introduced class syntax as a cleaner way to work with JavaScript's prototype-based inheritance model. Classes are syntactic sugar over constructor functions and prototypes — they do not introduce a new object model.

Class Declaration

js
class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    return `${this.name} makes a sound.`;
  }
}
const a = new Animal("Cat");

The constructor method runs automatically when you create an instance with new. Properties assigned to this inside the constructor become instance properties.

Methods

Methods defined inside the class body are placed on the prototype and shared by all instances — they are not copied per instance, which is memory-efficient.

Getters & Setters

get and set accessors let you define computed properties that look like regular properties from the outside:

js
class Circle {
  constructor(radius) { this.radius = radius; }
  get area() { return Math.PI * this.radius ** 2; }
  set diameter(d) { this.radius = d / 2; }
}
const c = new Circle(5);
c.area;      // computed, no ()
c.diameter = 20; // triggers setter

Static Methods & Properties

static members belong to the class itself, not to instances. They are called on the class: ClassName.method().

js
class MathHelper {
  static square(n) { return n * n; }
  static PI = 3.14159;
}
MathHelper.square(4); // 16

Class Fields (ES2022)

Public class fields declared outside the constructor are a concise alternative to assigning this.prop inside the constructor.

js
class Counter {
  count = 0;          // public instance field
  increment() { this.count++; }
}

Code Examples

Class Declaration and Instantiationjavascript
class BankAccount {
  balance = 0;  // public class field

  constructor(owner, initialDeposit = 0) {
    this.owner   = owner;
    this.balance = initialDeposit;
  }

  deposit(amount) {
    if (amount <= 0) throw new Error("Amount must be positive");
    this.balance += amount;
    return this;   // enables chaining
  }

  withdraw(amount) {
    if (amount > this.balance) throw new Error("Insufficient funds");
    this.balance -= amount;
    return this;
  }

  toString() {
    return `${this.owner}: $${this.balance.toFixed(2)}`;
  }
}

const acct = new BankAccount("Alice", 100);
acct.deposit(50).deposit(25).withdraw(30);
console.log(acct.toString());
console.log(acct instanceof BankAccount);

Class fields provide clean instance property initialization. Returning this from methods enables fluent/method-chaining APIs. instanceof confirms the object's class lineage.

Getters, Setters, and Static Membersjavascript
class Temperature {
  static absoluteZero = -273.15;

  constructor(celsius) {
    this._celsius = celsius;
  }

  get fahrenheit() {
    return this._celsius * 9 / 5 + 32;
  }

  set fahrenheit(f) {
    this._celsius = (f - 32) * 5 / 9;
  }

  get celsius() { return this._celsius; }
  set celsius(c) {
    if (c < Temperature.absoluteZero) throw new RangeError("Below absolute zero");
    this._celsius = c;
  }

  static fromFahrenheit(f) {
    return new Temperature((f - 32) * 5 / 9);
  }
}

const t = new Temperature(100);
console.log(t.fahrenheit);        // 212

t.fahrenheit = 32;
console.log(t.celsius.toFixed(1)); // 0.0

const body = Temperature.fromFahrenheit(98.6);
console.log(body.celsius.toFixed(1)); // 37.0
console.log(Temperature.absoluteZero);

Getters compute values on access (no parentheses needed). Setters validate and transform input before storing. Static factory methods like fromFahrenheit provide alternative constructors.

Methods on the Prototypejavascript
class Vector {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  add(other) {
    return new Vector(this.x + other.x, this.y + other.y);
  }

  scale(factor) {
    return new Vector(this.x * factor, this.y * factor);
  }

  get magnitude() {
    return Math.sqrt(this.x ** 2 + this.y ** 2);
  }

  toString() {
    return `Vector(${this.x}, ${this.y})`;
  }
}

const v1 = new Vector(3, 4);
const v2 = new Vector(1, 2);

console.log(v1.add(v2).toString());
console.log(v1.scale(2).toString());
console.log(v1.magnitude);

// Methods are on the prototype, not on instances
console.log(v1.add === v2.add);

Returning new instances from methods keeps objects immutable and composable. The last assertion proves methods live on the shared prototype, not duplicated on each instance.

Quick Quiz

1. What is the purpose of the constructor method in a class?

2. How do you call a static method called 'create' on a class named 'User'?

3. What syntax is used to define a computed property getter named 'fullName' in a class?

Was this lesson helpful?

PreviousNext