# Bab 6: Modern JavaScript (ES6+)

## Bab 6: Modern JavaScript (ES6+)

### 6.1 Arrow Functions

#### 6.1.1 Basic Syntax

```javascript
// Traditional function
function add(a, b) {
    return a + b;
}

// Arrow function
const add = (a, b) => a + b;

// Arrow function with block
const calculate = (a, b) => {
    const result = a * b;
    return result;
};

// Single parameter (parentheses optional)
const square = x => x * x;

// No parameters
const sayHello = () => 'Hello!';

// Returning object literals
const createUser = (name, age) => ({ name, age });
```

#### 6.1.2 Lexical This

```javascript
// Traditional function with 'this' binding issues
class Timer {
    constructor() {
        this.seconds = 0;
        setInterval(function() {
            this.seconds++; // 'this' is undefined
        }, 1000);
    }
}

// Arrow function with lexical 'this'
class Timer {
    constructor() {
        this.seconds = 0;
        setInterval(() => {
            this.seconds++; // 'this' refers to Timer instance
        }, 1000);
    }
}
```

### 6.2 Template Literals

#### 6.2.1 Basic Usage

```javascript
// String interpolation
const name = 'John';
const greeting = `Hello, ${name}!`;

// Multiline strings
const multiline = `
    This is a
    multiline
    string
`;

// Expression interpolation
const a = 10;
const b = 20;
console.log(`Sum: ${a + b}`);

// Tagged templates
function myTag(strings, ...values) {
    return strings.reduce((result, str, i) => 
        `${result}${str}${values[i] || ''}`, '');
}

const result = myTag`Sum of ${a} and ${b} is ${a + b}`;
```

### 6.3 Destructuring

#### 6.3.1 Array Destructuring

```javascript
// Basic array destructuring
const numbers = [1, 2, 3];
const [first, second, third] = numbers;

// Skipping elements
const [a, , c] = numbers;

// Rest operator
const [head, ...tail] = numbers;

// Default values
const [x = 0, y = 0, z = 0] = [1, 2];

// Swapping variables
let m = 1, n = 2;
[m, n] = [n, m];
```

#### 6.3.2 Object Destructuring

```javascript
// Basic object destructuring
const user = { name: 'John', age: 30 };
const { name, age } = user;

// Renaming properties
const { name: userName, age: userAge } = user;

// Default values
const { name = 'Anonymous', country = 'Unknown' } = user;

// Nested destructuring
const data = {
    user: {
        address: {
            street: 'Main St',
            city: 'Boston'
        }
    }
};
const { user: { address: { city } } } = data;

// Rest operator with objects
const { name, ...rest } = user;
```

### 6.4 Spread dan Rest Operator

#### 6.4.1 Spread Operator

```javascript
// Array spreading
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];

// Object spreading
const obj1 = { foo: 'bar', x: 42 };
const obj2 = { ...obj1, y: 13 };

// Array copying
const original = [1, 2, 3];
const copy = [...original];

// Function arguments
const numbers = [1, 2, 3];
console.log(Math.max(...numbers));

// Merging arrays/objects
const array1 = [1, 2];
const array2 = [3, 4];
const merged = [...array1, ...array2];

const obj1 = { foo: 'bar' };
const obj2 = { baz: 42 };
const merged = { ...obj1, ...obj2 };
```

#### 6.4.2 Rest Parameter

```javascript
// Rest parameters in functions
function sum(...numbers) {
    return numbers.reduce((total, num) => total + num, 0);
}

// Combining with regular parameters
function multiply(multiplier, ...numbers) {
    return numbers.map(num => multiplier * num);
}

// Object rest properties
const { a, b, ...rest } = { a: 1, b: 2, c: 3, d: 4 };
```

### 6.5 Modules

#### 6.5.1 Module Syntax

```javascript
// Exporting
export const pi = 3.14159;
export function square(x) {
    return x * x;
}
export class Circle {
    constructor(radius) {
        this.radius = radius;
    }
}

// Default export
export default class User {
    constructor(name) {
        this.name = name;
    }
}

// Importing
import User from './User.js';
import { pi, square } from './math.js';
import * as mathUtils from './math.js';
import { rename as newName } from './module.js';
```

### 6.6 Map dan Set

#### 6.6.1 Map

```javascript
// Creating a Map
const map = new Map();

// Setting values
map.set('key1', 'value1');
map.set(42, 'number key');
map.set(obj, 'object key');

// Getting values
console.log(map.get('key1'));

// Checking existence
console.log(map.has('key1'));

// Deleting entries
map.delete('key1');

// Size and clearing
console.log(map.size);
map.clear();

// Iteration
map.forEach((value, key) => {
    console.log(`${key} = ${value}`);
});

for (const [key, value] of map) {
    console.log(`${key} = ${value}`);
}
```

#### 6.6.2 Set

```javascript
// Creating a Set
const set = new Set([1, 2, 3, 3]); // Duplicates removed

// Adding values
set.add(4);
set.add(5);

// Checking existence
console.log(set.has(4));

// Deleting values
set.delete(4);

// Size and clearing
console.log(set.size);
set.clear();

// Iteration
set.forEach(value => {
    console.log(value);
});

for (const value of set) {
    console.log(value);
}
```

### 6.7 Optional Chaining dan Nullish Coalescing

#### 6.7.1 Optional Chaining

```javascript
// Object properties
const user = {
    address: {
        street: 'Main St'
    }
};
console.log(user?.address?.street);

// Method calls
const response = object?.getValue?.();

// Array elements
const arr = [1, 2, 3];
console.log(arr?.[0]);
```

#### 6.7.2 Nullish Coalescing

```javascript
// Basic usage
const value = null ?? 'default';
const zero = 0 ?? 42;
const empty = '' ?? 'default';

// Chaining with optional chaining
const street = user?.address?.street ?? 'Unknown Street';

// Comparison with OR operator
const withOr = '' || 'default';      // 'default'
const withNullish = '' ?? 'default'; // ''
```

### 6.8 Modern Features dan Syntax

#### 6.8.1 Object Methods

```javascript
// Object.entries()
const obj = { a: 1, b: 2 };
for (const [key, value] of Object.entries(obj)) {
    console.log(`${key}: ${value}`);
}

// Object.fromEntries()
const entries = [['a', 1], ['b', 2]];
const object = Object.fromEntries(entries);

// Object.values()
console.log(Object.values(obj));

// Object property shorthand
const name = 'John';
const age = 30;
const user = { name, age };
```

### 6.9 Praktik dan Latihan

#### 6.9.1 Modern Code Refactoring

```javascript
// Before
function getUser(id, callback) {
    return fetch('/api/users/' + id)
        .then(function(response) {
            return response.json();
        })
        .then(function(user) {
            callback(null, user);
        })
        .catch(function(error) {
            callback(error);
        });
}

// After
const getUser = async (id) => {
    try {
        const response = await fetch(`/api/users/${id}`);
        return await response.json();
    } catch (error) {
        throw error;
    }
};
```

### 6.10 Best Practices

* When to use arrow functions vs regular functions
* Module organization and structure
* Destructuring patterns
* Performance considerations
* Modern syntax adoption strategies

### 6.11 Ringkasan

* Modern JavaScript features and syntax
* ES6+ enhancements
* Code organization and structure
* Best practices and patterns

### 6.12 Latihan Akhir Bab

1. Refactor legacy code using modern syntax
2. Implement a module system
3. Create a data processing utility using modern features
4. Build a configuration system using modern patterns
5. Implement a caching system using Map/Set


---

# 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-6-modern-javascript-es6+.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.
