Classes
## Learning Objectives
- Understand ES6 class syntax
- Master inheritance with extends
- Learn about static methods and properties
- Explore private fields
## Class Declarations
```javascript
class Person {
// Constructor
constructor(name, age) {
this.name = name;
this.age = age;
}
// Method
greet() {
return `Hello, I'm ${this.name}`;
}
}
const person = new Person("Alice", 30);
person.greet(); // "Hello, I'm Alice"
```
## Class Expressions
```javascript
const Person = class {
constructor(name) {
this.name = name;
}
};
```
## Constructor
```javascript
class Person {
constructor(name, age = 18) {
this.name = name;
this.age = age;
}
}
const person = new Person("Alice");
console.log(person.age); // 18 (default value)
```
## Methods
### Instance Methods
```javascript
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, I'm ${this.name}`;
}
}
```
### Static Methods
```javascript
class Person {
constructor(name) {
this.name = name;
}
static createAnonymous() {
return new Person("Anonymous");
}
}
const anon = Person.createAnonymous();
```
### Getters and Setters
```javascript
class Person {
constructor(name) {
this._name = name;
}
get name() {
return this._name.toUpperCase();
}
set name(value) {
this._name = value;
}
}
const person = new Person("Alice");
console.log(person.name); // "ALICE"
person.name = "Bob";
console.log(person.name); // "BOB"
```
## Inheritance
### extends Keyword
```javascript
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound`;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Call parent constructor
this.breed = breed;
}
speak() {
return `${this.name} barks`;
}
}
const dog = new Dog("Rex", "German Shepherd");
dog.speak(); // "Rex barks"
dog.name; // "Rex"
```
### super Keyword
```javascript
class Cat extends Animal {
constructor(name, indoor) {
super(name);
this.indoor = indoor;
}
speak() {
return super.speak() + " and meows"; // Call parent method
}
}
```
## Private Fields
### Using # Prefix (ES2022)
```javascript
class BankAccount {
#balance; // Private field
constructor(initialBalance) {
this.#balance = initialBalance;
}
deposit(amount) {
this.#balance += amount;
return this.#balance;
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount(100);
account.deposit(50);
console.log(account.getBalance()); // 150
// account.#balance; // SyntaxError!
```
### Private Methods
```javascript
class Calculator {
#validate(num) {
return typeof num === "number" && !isNaN(num);
}
add(a, b) {
if (!this.#validate(a) || !this.#validate(b)) {
throw new Error("Invalid number");
}
return a + b;
}
}
```
## Static Blocks (ES2022)
```javascript
class MyConfig {
static apiUrl;
static apiKey;
static databaseUrl;
static {
// Complex static initialization
const env = process.env.NODE_ENV;
this.apiUrl = env === "production"
? "https://api.example.com"
: "https://dev.api.example.com";
}
}
```
## Class Fields
```javascript
class Person {
name = "Unknown"; // Public field
age; // Public field (undefined by default)
#secret = "hidden"; // Private field
static species = "Human"; // Static field
}
```
## Prototype Methods vs Class Methods
```javascript
class Person {
constructor(name) {
this.name = name;
}
// Instance method - on prototype
greet() {
return `Hello, I'm ${this.name}`;
}
}
// Same as:
Person.prototype.greet = function() {
return `Hello, I'm ${this.name}`;
};
```
## Checking Class Type
```javascript
class Dog extends Animal {}
const dog = new Dog("Rex");
dog instanceof Dog; // true
dog instanceof Animal; // true
dog instanceof Object; // true
```
## Mixins
```javascript
const Flyable = {
fly() {
return `${this.name} flies!`;
}
};
const Swimmable = {
swim() {
return `${this.name} swims!`;
}
};
class Duck {
constructor(name) {
this.name = name;
}
}
Object.assign(Duck.prototype, Flyable, Swimmable);
const duck = new Duck("Donald");
duck.fly(); // "Donald flies!"
duck.swim(); // "Donald swims!"
```
## Abstract Classes
```javascript
class Shape {
constructor() {
if (this.constructor === Shape) {
throw new Error("Cannot instantiate abstract class");
}
}
area() {
throw new Error("Method 'area' must be implemented");
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
}
```
## Summary
- ES6 classes provide cleaner syntax for constructor functions and prototypes
- `extends` enables inheritance
- Use `super()` to call parent constructor or methods
- Private fields (`#field`) restrict access from outside
- Static methods belong to the class itself, not instances
- Classes are syntactic sugar over JavaScript's prototype-based inheritance
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →