# Bab 3: Object-Oriented Programming dalam JavaScript

## Bab 3: Object-Oriented Programming dalam JavaScript

### 3.1 Konsep Dasar OOP

#### 3.1.1 Pengenalan OOP

* Definisi Object-Oriented Programming
* Keuntungan menggunakan OOP
* Perbedaan OOP dengan functional programming
* Use cases untuk OOP dalam JavaScript

#### 3.1.2 Empat Pilar OOP

```javascript
/*
1. Encapsulation: Membungkus data dan method yang memanipulasi data dalam satu unit
2. Inheritance: Mewarisi properties dan methods dari class lain
3. Polymorphism: Kemampuan object untuk mengambil berbagai bentuk
4. Abstraction: Menyembunyikan kompleksitas dan hanya menunjukkan fungsionalitas yang diperlukan
*/
```

### 3.2 Constructor dan Class

#### 3.2.1 Constructor Functions (Pre-ES6)

```javascript
// Constructor function
function Person(name, age) {
    this.name = name;
    this.age = age;
    
    this.greet = function() {
        return `Hello, I'm ${this.name}`;
    };
}

// Creating instances
const person1 = new Person("John", 30);
const person2 = new Person("Jane", 25);

console.log(person1.greet()); // "Hello, I'm John"
```

#### 3.2.2 ES6 Class Syntax

```javascript
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    greet() {
        return `Hello, I'm ${this.name}`;
    }
    
    // Static method
    static createAnonymous() {
        return new Person("Anonymous", 0);
    }
    
    // Getter
    get info() {
        return `${this.name} is ${this.age} years old`;
    }
    
    // Setter
    set info(value) {
        [this.name, this.age] = value.split(' ');
    }
}
```

### 3.3 Inheritance

#### 3.3.1 Prototypal Inheritance

```javascript
// Base constructor
function Animal(name) {
    this.name = name;
}

Animal.prototype.makeSound = function() {
    console.log("Some sound");
};

// Inheriting constructor
function Dog(name, breed) {
    Animal.call(this, name);
    this.breed = breed;
}

// Setting up inheritance
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// Adding method to Dog
Dog.prototype.bark = function() {
    console.log("Woof!");
};
```

#### 3.3.2 Class Inheritance (ES6)

```javascript
class Animal {
    constructor(name) {
        this.name = name;
    }
    
    makeSound() {
        console.log("Some sound");
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }
    
    bark() {
        console.log("Woof!");
    }
}

const myDog = new Dog("Rex", "German Shepherd");
myDog.makeSound(); // Inherited method
myDog.bark();     // Own method
```

### 3.4 Encapsulation

#### 3.4.1 Private Fields dan Methods (ES2022)

```javascript
class BankAccount {
    #balance = 0; // Private field
    
    constructor(initialBalance) {
        this.#balance = initialBalance;
    }
    
    #validateAmount(amount) { // Private method
        return amount > 0 && amount <= this.#balance;
    }
    
    withdraw(amount) {
        if (this.#validateAmount(amount)) {
            this.#balance -= amount;
            return true;
        }
        return false;
    }
    
    getBalance() {
        return this.#balance;
    }
}
```

#### 3.4.2 Closure untuk Private Data

```javascript
function createCounter() {
    let count = 0; // Private variable
    
    return {
        increment() {
            count++;
            return count;
        },
        decrement() {
            count--;
            return count;
        },
        getCount() {
            return count;
        }
    };
}

const counter = createCounter();
```

### 3.5 Polymorphism

#### 3.5.1 Method Overriding

```javascript
class Shape {
    calculateArea() {
        return 0;
    }
}

class Circle extends Shape {
    constructor(radius) {
        super();
        this.radius = radius;
    }
    
    calculateArea() {
        return Math.PI * this.radius ** 2;
    }
}

class Rectangle extends Shape {
    constructor(width, height) {
        super();
        this.width = width;
        this.height = height;
    }
    
    calculateArea() {
        return this.width * this.height;
    }
}
```

#### 3.5.2 Interface-like Behavior

```javascript
class DataStorage {
    save(data) {
        throw new Error("Method 'save' must be implemented");
    }
    
    load() {
        throw new Error("Method 'load' must be implemented");
    }
}

class FileStorage extends DataStorage {
    save(data) {
        console.log("Saving to file:", data);
    }
    
    load() {
        return "Data from file";
    }
}

class DatabaseStorage extends DataStorage {
    save(data) {
        console.log("Saving to database:", data);
    }
    
    load() {
        return "Data from database";
    }
}
```

### 3.6 Prototype dan Prototype Chain

#### 3.6.1 Understanding Prototypes

```javascript
function Student(name) {
    this.name = name;
}

Student.prototype.study = function() {
    console.log(`${this.name} is studying`);
};

const student1 = new Student("Alice");

console.log(student1.__proto__ === Student.prototype); // true
console.log(Student.prototype.__proto__ === Object.prototype); // true
```

#### 3.6.2 Prototype Methods dan Properties

```javascript
// Adding methods to built-in objects (not recommended in production)
Array.prototype.sum = function() {
    return this.reduce((a, b) => a + b, 0);
};

const numbers = [1, 2, 3, 4];
console.log(numbers.sum()); // 10
```

### 3.7 Design Patterns

#### 3.7.1 Singleton Pattern

```javascript
class Singleton {
    static #instance;
    
    constructor() {
        if (Singleton.#instance) {
            return Singleton.#instance;
        }
        Singleton.#instance = this;
    }
    
    static getInstance() {
        if (!Singleton.#instance) {
            Singleton.#instance = new Singleton();
        }
        return Singleton.#instance;
    }
}
```

#### 3.7.2 Factory Pattern

```javascript
class Vehicle {
    constructor(type, model) {
        this.type = type;
        this.model = model;
    }
}

class VehicleFactory {
    createVehicle(type, model) {
        switch(type) {
            case 'car':
                return new Car(model);
            case 'truck':
                return new Truck(model);
            default:
                throw new Error('Unknown vehicle type');
        }
    }
}
```

### 3.8 Praktik dan Latihan

#### 3.8.1 Project: Library Management System

```javascript
class Book {
    #isbn;
    constructor(title, author, isbn) {
        this.title = title;
        this.author = author;
        this.#isbn = isbn;
    }
}

class Library {
    #books = new Map();
    
    addBook(book) {
        // Implementation
    }
    
    removeBook(isbn) {
        // Implementation
    }
    
    findBook(isbn) {
        // Implementation
    }
}
```

#### 3.8.2 Project: Shopping Cart System

```javascript
class Product {
    constructor(id, name, price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
}

class ShoppingCart {
    #items = new Map();
    
    addItem(product, quantity) {
        // Implementation
    }
    
    removeItem(productId) {
        // Implementation
    }
    
    calculateTotal() {
        // Implementation
    }
}
```

### 3.9 Best Practices dan Common Pitfalls

* Avoiding global scope pollution
* Proper use of 'this'
* When to use inheritance vs composition
* Performance considerations
* Memory management
* Error handling in OOP

### 3.10 Ringkasan

* OOP fundamentals in JavaScript
* Modern vs traditional approaches
* Design patterns dan use cases
* Best practices dan pitfalls

### 3.11 Latihan Akhir Bab

1. Implement a bank account system
2. Create a school management system
3. Build a simple game using OOP
4. Implement common design patterns
5. Refactor functional code to OOP


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://triyono.gitbook.io/tutorial/java-script/bab-3-object-oriented-programming-dalam-javascript.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
