Classes dan Object Literals
Memahami default parameters, ES6 classes, dan enhanced object literals
Default Parameters
Default parameters memungkinkanKalianmenentukan nilai default untuk parameter function yang tidak diberikan atau undefined.
Perbandingan dengan ES5
// Cara lama dengan OR operator
function greet(name, greeting) {
name = name || "Guest";
greeting = greeting || "Hello";
return greeting + ", " + name + "!";
}// Dengan default parameters
function greet(name = "Guest", greeting = "Hello") {
return `${greeting}, ${name}!`;
}Keuntungan Default Parameters
- Lebih jelas dan ekspresif
- Dapat menggunakan nilai falsy (0, "", false) tanpa di-override
- Dapat menggunakan ekspresi sebagai default value
- Dapat mereferensi parameter sebelumnya
Implementasi Default Parameters
Tambahkan ke js/app.js:
// ----------------------------
// Default Parameters
// ----------------------------
export function demoDefaultParams() {
// Cara lama (ES5)
function greetOld(name, greeting) {
name = name || "Guest";
greeting = greeting || "Hello";
return `${greeting}, ${name}!`;
}
// Dengan default parameters (ES6)
function greet(name = "Guest", greeting = "Hello") {
return `${greeting}, ${name}!`;
}
// Default parameters dengan ekspresi
function createUser(name, role = "user", createdAt = new Date().toISOString()) {
return { name, role, createdAt };
}
// Default parameters bisa menggunakan parameter sebelumnya
function createOrder(product, quantity = 1, price, total = price * quantity) {
return { product, quantity, price, total };
}
return {
oldWay: greetOld(),
oldWayParams: greetOld("John", "Hi"),
newWay: greet(),
newWayParams: greet("John", "Hi"),
withExpression: createUser("Alice"),
usingPrevious: createOrder("Laptop", 2, 1000000)
};
}ES6 Classes
Classes di ES6 menyediakan sintaks yang lebih bersih untuk membuat objek dan menangani inheritance.
Sintaks Dasar Class
class User {
// Constructor
constructor(name, email) {
this.name = name;
this.email = email;
this.createdAt = new Date();
}
// Method
getInfo() {
return `${this.name} (${this.email})`;
}
// Getter
get age() {
return new Date().getFullYear() - this.birthYear;
}
// Setter
set birthYear(year) {
this._birthYear = year;
}
// Static method
static create(name, email) {
return new User(name, email);
}
}Inheritance dengan extends
class Admin extends User {
constructor(name, email, role = "admin") {
super(name, email); // Panggil constructor parent
this.role = role;
}
// Override method
getInfo() {
return `${super.getInfo()} - ${this.role}`;
}
// Method baru
hasAccess(module) {
return true;
}
}Implementasi Classes
Tambahkan ke js/app.js:
// ----------------------------
// Classes
// ----------------------------
export function demoClasses() {
// Definisi class
class User {
// Constructor
constructor(name, email) {
this.name = name;
this.email = email;
this.createdAt = new Date();
}
// Methods
getInfo() {
return `${this.name} (${this.email})`;
}
getCreatedDate() {
return this.createdAt.toLocaleDateString();
}
}
// Inheritance
class Admin extends User {
constructor(name, email, role = "admin") {
// Memanggil constructor parent class
super(name, email);
this.role = role;
}
// Override method
getInfo() {
return `${this.name} (${this.email}) - ${this.role}`;
}
// Admin method
hasAccess(module) {
return true; // Untuk contoh, admin selalu punya akses
}
}
// Instances
const user = new User("John Doe", "john@example.com");
const admin = new Admin("Admin User", "admin@example.com");
return {
user: {
info: user.getInfo(),
createdDate: user.getCreatedDate()
},
admin: {
info: admin.getInfo(),
createdDate: admin.getCreatedDate(),
hasAccess: admin.hasAccess("dashboard")
},
isUserInstance: user instanceof User,
isAdminInstance: admin instanceof User // true karena inheritance
};
}Class vs Prototype
Classes di JavaScript adalah syntactic sugar di atas prototype-based inheritance yang sudah ada. Di bawah hood, mereka tetap menggunakan prototypes, tetapi dengan sintaks yang lebih familiar bagi developer dari bahasa OOP lain.
Enhanced Object Literals
ES6 memperkenalkan beberapa peningkatan pada object literals yang membuat kode lebih ringkas.
Fitur-fitur Enhanced Object Literals
const name = "John";
const age = 30;
// Old way
const person = {
name: name,
age: age
};
// Property shorthand
const person = {
name,
age
};// Old way
const obj = {
sayHello: function() {
return "Hello!";
}
};
// Method shorthand
const obj = {
sayHello() {
return "Hello!";
}
};const prefix = "user";
const id = 123;
// Computed property names
const userData = {
[`${prefix}_id`]: id,
[`${prefix}_name`]: "john_doe",
[Date.now()]: "timestamp"
};Implementasi Enhanced Object Literals
Tambahkan ke js/app.js:
// ----------------------------
// Enhanced Object Literals
// ----------------------------
export function demoObjectLiterals() {
// Property shorthand
const name = "John";
const age = 30;
// Cara lama
const oldPerson = {
name: name,
age: age,
sayHello: function() {
return "Hello!";
}
};
// Object literal modern (ES6)
const newPerson = {
name,
age,
// Method shorthand
sayHello() {
return "Hello!";
},
// Computed property names
["skill_" + 1]: "JavaScript",
["skill_" + 2]: "React"
};
// Combining with other features
const prefix = "user";
const userData = {
[`${prefix}_id`]: 123,
[`${prefix}_name`]: "john_doe",
[Date.now()]: "timestamp"
};
return {
oldWay: oldPerson,
newWay: newPerson,
methods: {
old: oldPerson.sayHello(),
new: newPerson.sayHello()
},
computedProps: {
skill1: newPerson.skill_1,
skill2: newPerson.skill_2
},
dynamicProps: userData
};
}Update main.js
Update js/main.js untuk menjalankan demo baru:
// Update import
import {
demoVariables,
demoArrowFunctions,
demoTemplateLiterals,
demoDestructuring,
demoSpreadRest,
demoDefaultParams,
demoClasses,
demoObjectLiterals
} from './app.js';
// Tambahkan ke fungsi runAllDemos
function runAllDemos() {
// ... demo sebelumnya ...
// Demo Default Parameters
const defaultParamsResults = demoDefaultParams();
addOutput(
"6. Default Parameters",
"Nilai default untuk parameter fungsi",
`Old way: ${defaultParamsResults.oldWay}
Old way with params: ${defaultParamsResults.oldWayParams}
New way: ${defaultParamsResults.newWay}
New way with params: ${defaultParamsResults.newWayParams}
With expression: ${JSON.stringify(defaultParamsResults.withExpression)}
Using previous params: ${JSON.stringify(defaultParamsResults.usingPrevious)}`
);
// Demo Classes
const classesResults = demoClasses();
addOutput(
"7. Classes",
"Penggunaan class dan inheritance",
`User: ${classesResults.user.info}
User created: ${classesResults.user.createdDate}
Admin: ${classesResults.admin.info}
Admin created: ${classesResults.admin.createdDate}
Admin has access: ${classesResults.admin.hasAccess}
user instanceof User: ${classesResults.isUserInstance}
admin instanceof User: ${classesResults.isAdminInstance}`
);
// Demo Enhanced Object Literals
const objectLiteralsResults = demoObjectLiterals();
addOutput(
"8. Enhanced Object Literals",
"Penulisan objek yang lebih ringkas",
`Property shorthand: ${JSON.stringify(objectLiteralsResults.newWay)}
Method shorthand: ${objectLiteralsResults.methods.new}
Computed properties: ${JSON.stringify(objectLiteralsResults.computedProps)}
Dynamic properties: ${JSON.stringify(objectLiteralsResults.dynamicProps)}`
);
}Praktik Terbaik
1. Gunakan Default Parameters
// Good
function createUser(name, role = "user", active = true) {
return { name, role, active };
}
// Avoid
function createUser(name, role, active) {
role = role || "user";
active = active !== undefined ? active : true;
return { name, role, active };
}2. Class untuk Domain Models
class Product {
constructor(name, price) {
this.name = name;
this.price = price;
}
getDiscountedPrice(discount) {
return this.price * (1 - discount);
}
toString() {
return `${this.name}: Rp${this.price.toLocaleString()}`;
}
}3. Property Shorthand untuk Clean Code
// Good - clean and concise
const user = { name, email, age };
// Avoid - redundant
const user = { name: name, email: email, age: age };When to Use Classes
Gunakan classes ketika: -Kalian membutuhkan multiple instances dengan behavior yang sama
- Inheritance diperlukan
- Encapsulation penting untuk domain model
Hindari over-engineering dengan classes untuk simple data structures yang bisa menggunakan plain objects.
Latihan
- Buat class
Productdengan inheritance keDigitalProductdanPhysicalProduct - Implementasi getter dan setter dalam class
- Gunakan computed property names untuk membuat object dengan dynamic keys
- Combine default parameters dengan destructuring dalam function parameter
