Bab 6: Modern JavaScript (ES6+)

Bab 6: Modern JavaScript (ES6+)

6.1 Arrow Functions

6.1.1 Basic Syntax

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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

Last updated