JavaScript ES2024: Fitur-Fitur Baru yang Wajib Diketahui Developer
JavaScript terus berkembang dengan fitur-fitur baru yang memudahkan developer. ES2024 (ECMAScript 2024) membawa beberapa addition yang sangat berguna untuk development modern.
1. Array Grouping dengan Object.groupBy()
Fitur yang sangat dinanti untuk mengelompokkan array berdasarkan kriteria tertentu:
const products = [
{ name: 'Laptop', category: 'Electronics', price: 1000 },
{ name: 'Shirt', category: 'Clothing', price: 50 },
{ name: 'Phone', category: 'Electronics', price: 800 },
{ name: 'Jeans', category: 'Clothing', price: 80 }
];
// Grouping by category
const groupedByCategory = Object.groupBy(products, product => product.category);
console.log(groupedByCategory);
// {
// Electronics: [
// { name: 'Laptop', category: 'Electronics', price: 1000 },
// { name: 'Phone', category: 'Electronics', price: 800 }
// ],
// Clothing: [
// { name: 'Shirt', category: 'Clothing', price: 50 },
// { name: 'Jeans', category: 'Clothing', price: 80 }
// ]
// }
Use Cases Praktis
// Group users by age range
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 35 },
{ name: 'Charlie', age: 28 }
];
const groupedByAgeRange = Object.groupBy(users, user => {
if (user.age < 30) return 'Young';
if (user.age < 40) return 'Middle';
return 'Senior';
});
2. Map.groupBy() untuk Map Objects
Similar dengan Object.groupBy(), tapi return Map instead:
const transactions = [
{ id: 1, type: 'income', amount: 1000 },
{ id: 2, type: 'expense', amount: 500 },
{ id: 3, type: 'income', amount: 750 }
];
const groupedTransactions = Map.groupBy(transactions, t => t.type);
console.log(groupedTransactions.get('income'));
// [{ id: 1, type: 'income', amount: 1000 }, { id: 3, type: 'income', amount: 750 }]
3. Promise.withResolvers()
Cara baru untuk membuat Promise dengan resolver dan rejecter yang exposed:
// Old way
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
// New way with Promise.withResolvers()
const { promise, resolve, reject } = Promise.withResolvers();
// Practical example
function createTimeoutPromise(delay) {
const { promise, resolve } = Promise.withResolvers();
setTimeout(() => {
resolve(`Completed after ${delay}ms`);
}, delay);
return promise;
}
// Usage
createTimeoutPromise(1000).then(console.log);
Real-world Example
class EventEmitter {
constructor() {
this.listeners = new Map();
}
waitForEvent(eventName) {
const { promise, resolve } = Promise.withResolvers();
const listener = (data) => {
resolve(data);
this.off(eventName, listener);
};
this.on(eventName, listener);
return promise;
}
}
4. Atomics.waitAsync()
Non-blocking version dari Atomics.wait():
// Shared memory between workers
const sharedBuffer = new SharedArrayBuffer(1024);
const sharedArray = new Int32Array(sharedBuffer);
// Non-blocking wait
const result = Atomics.waitAsync(sharedArray, 0, 0);
if (result.async) {
result.value.then(() => {
console.log('Value changed!');
});
} else {
console.log('Value already changed');
}
5. String.prototype.isWellFormed()
Check apakah string memiliki well-formed Unicode:
const validString = "Hello 👋";
const invalidString = "\uD800"; // Lone surrogate
console.log(validString.isWellFormed()); // true
console.log(invalidString.isWellFormed()); // false
// Practical usage
function safeStringOperation(str) {
if (!str.isWellFormed()) {
throw new Error('Invalid Unicode string');
}
return str.toWellFormed();
}
6. String.prototype.toWellFormed()
Convert string menjadi well-formed Unicode:
const malformedString = "Hello\uD800World";
const wellFormedString = malformedString.toWellFormed();
console.log(wellFormedString); // "Hello�World" (� replaces invalid surrogate)
7. ArrayBuffer Transfer
Transfer ownership dari ArrayBuffer:
const buffer1 = new ArrayBuffer(1024);
const view1 = new Uint8Array(buffer1);
// Fill with some data
view1[0] = 42;
// Transfer to new buffer
const buffer2 = buffer1.transfer();
const view2 = new Uint8Array(buffer2);
console.log(view2[0]); // 42
console.log(buffer1.byteLength); // 0 (transferred)
console.log(buffer2.byteLength); // 1024
Resize ArrayBuffer
const buffer = new ArrayBuffer(1024, { maxByteLength: 2048 });
// Resize to larger size
buffer.resize(1536);
console.log(buffer.byteLength); // 1536
// Transfer with different size
const newBuffer = buffer.transfer(512);
console.log(newBuffer.byteLength); // 512
8. RegExp v Flag
Enhanced Unicode support untuk regular expressions:
// Old way - limited Unicode support
const oldRegex = /[\u{1F600}-\u{1F64F}]/u;
// New way - better Unicode property support
const newRegex = /[\p{Emoji_Presentation}]/v;
const text = "Hello 😀 World 🌍";
console.log(text.match(newRegex)); // Better emoji matching
Browser Support dan Polyfills
Checking Support
// Check for Object.groupBy support
if (typeof Object.groupBy === 'function') {
// Use native implementation
const grouped = Object.groupBy(array, callback);
} else {
// Use polyfill or fallback
const grouped = customGroupBy(array, callback);
}
Simple Polyfill Example
// Simple Object.groupBy polyfill
if (!Object.groupBy) {
Object.groupBy = function(array, callback) {
const result = {};
for (let i = 0; i < array.length; i++) {
const key = callback(array[i], i);
if (!result[key]) {
result[key] = [];
}
result[key].push(array[i]);
}
return result;
};
}
Best Practices
1. Progressive Enhancement
// Use feature detection
const groupData = (array, callback) => {
if (Object.groupBy) {
return Object.groupBy(array, callback);
}
// Fallback implementation
return array.reduce((groups, item) => {
const key = callback(item);
groups[key] = groups[key] || [];
groups[key].push(item);
return groups;
}, {});
};
2. TypeScript Support
// Type definitions for new features
interface ObjectConstructor {
groupBy<T, K extends PropertyKey>(
array: T[],
callback: (item: T, index: number) => K
): Record<K, T[]>;
}
// Usage with types
const products: Product[] = [...];
const grouped: Record<string, Product[]> = Object.groupBy(
products,
product => product.category
);
Kesimpulan
ES2024 membawa improvement yang signifikan untuk:
- Data manipulation dengan Array/Map grouping
- Async programming dengan Promise.withResolvers()
- Unicode handling dengan string well-formed methods
- Memory management dengan ArrayBuffer transfer
Yang Perlu Diingat
Selalu check browser compatibility sebelum menggunakan fitur baru di production
Next Steps
- Experiment dengan fitur-fitur ini di development environment
- Setup polyfills untuk browser compatibility
- Update TypeScript untuk type support
- Monitor browser support untuk adoption timeline
Stay updated dengan perkembangan JavaScript terbaru dengan mengikuti blog ini!