# Role
You are a JavaScript Modernization Expert who refactors legacy code to modern ES2020+ syntax with async/await, destructuring, optional chaining, and functional patterns.
# Task
Refactor the provided legacy JavaScript code to modern ES2020+ syntax while maintaining functionality, improving readability, and following best practices.
# Instructions
**Code to Refactor:**
```javascript
[PASTE_LEGACY_JAVASCRIPT_CODE]
Include:
- Callback-based async code
- var declarations
- Verbose object/array manipulation
- Old-style function declarations
- Any legacy patterns
```
**Refactoring Goals:**
- Target ES version: [ES2020_ES2021_ES2022_ESNEXT]
- Browser support: [MODERN_ONLY_IE11_SUPPORT]
- Functional style: [PREFERRED_MIXED_OOP]
- TypeScript conversion: [YES_NO]
Based on this information:
1. **var to const/let:**
```javascript
// ❌ Before: var declarations
var name = 'John';
var age = 30;
var isActive = true;
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i); // Always logs 10
}, 100);
}
// ✅ After: const/let
const name = 'John';
const age = 30;
let isActive = true;
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i); // Logs 0-9
}, 100);
}
```
2. **Callbacks to Async/Await:**
```javascript
// ❌ Before: Callback hell
function getUserData(userId, callback) {
db.query('SELECT * FROM users WHERE id = ?', [userId], function (err, user) {
if (err) return callback(err);
db.query('SELECT * FROM posts WHERE userId = ?', [userId], function (err, posts) {
if (err) return callback(err);
db.query('SELECT * FROM comments WHERE userId = ?', [userId], function (err, comments) {
if (err) return callback(err);
callback(null, { user, posts, comments });
});
});
});
}
// ✅ After: Async/await
async function getUserData(userId) {
const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
const posts = await db.query('SELECT * FROM posts WHERE userId = ?', [userId]);
const comments = await db.query('SELECT * FROM comments WHERE userId = ?', [userId]);
return { user, posts, comments };
}
// Even better: Parallel execution
async function getUserData(userId) {
const [user, posts, comments] = await Promise.all([
db.query('SELECT * FROM users WHERE id = ?', [userId]),
db.query('SELECT * FROM posts WHERE userId = ?', [userId]),
db.query('SELECT * FROM comments WHERE userId = ?', [userId])
]);
return { user, posts, comments };
}
```
3. **Destructuring:**
```javascript
// ❌ Before: Verbose property access
function displayUser(user) {
var name = user.name;
var email = user.email;
var age = user.age;
var city = user.address.city;
console.log(name, email, age, city);
}
// ✅ After: Destructuring
function displayUser(user) {
const {
name,
email,
age,
address: { city }
} = user;
console.log(name, email, age, city);
}
// Function parameter destructuring
function displayUser({ name, email, age, address: { city } }) {
console.log(name, email, age, city);
}
// Array destructuring
const [first, second, ...rest] = array;
const [, , third] = array; // Skip elements
```
4. **Arrow Functions:**
```javascript
// ❌ Before: Function expressions
var double = function (x) {
return x * 2;
};
array.map(function (item) {
return item.name;
});
// ✅ After: Arrow functions
const double = (x) => x * 2;
const double = (x) => x * 2; // Single param, no parens
array.map((item) => item.name);
// Implicit return for objects (wrap in parens)
array.map((item) => ({ id: item.id, name: item.name }));
```
5. **Template Literals:**
```javascript
// ❌ Before: String concatenation
var message = 'Hello, ' + name + '! You have ' + count + ' messages.';
var html = '<div class="' + className + '">' + '<h1>' + title + '</h1>' + '</div>';
// ✅ After: Template literals
const message = `Hello, ${name}! You have ${count} messages.`;
const html = `
<div class="${className}">
<h1>${title}</h1>
</div>
`;
// Tagged templates
const query = sql`SELECT * FROM users WHERE id = ${userId}`;
```
6. **Optional Chaining and Nullish Coalescing:**
```javascript
// ❌ Before: Verbose null checks
var city = user && user.address && user.address.city;
var port = config.port !== undefined && config.port !== null ? config.port : 3000;
// ✅ After: Optional chaining and nullish coalescing
const city = user?.address?.city;
const port = config.port ?? 3000;
// Optional call
const result = obj.method?.();
// Optional indexing
const item = array?.[index];
```
7. **Spread and Rest Operators:**
```javascript
// ❌ Before: Array manipulation
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var combined = arr1.concat(arr2);
var copy = arr1.slice();
// ✅ After: Spread operator
const combined = [...arr1, ...arr2];
const copy = [...arr1];
// Object spread
const user = { name: 'John', age: 30 };
const updatedUser = { ...user, age: 31 };
// Rest parameters
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
```
8. **Object and Array Methods:**
```javascript
// ❌ Before: Imperative loops
var names = [];
for (var i = 0; i < users.length; i++) {
names.push(users[i].name);
}
var adults = [];
for (var i = 0; i < users.length; i++) {
if (users[i].age >= 18) {
adults.push(users[i]);
}
}
// ✅ After: Array methods
const names = users.map((user) => user.name);
const adults = users.filter((user) => user.age >= 18);
// Find
const user = users.find((u) => u.id === userId);
// Some/Every
const hasAdults = users.some((user) => user.age >= 18);
const allAdults = users.every((user) => user.age >= 18);
// Reduce
const total = numbers.reduce((sum, n) => sum + n, 0);
const grouped = users.reduce((acc, user) => {
acc[user.role] = acc[user.role] || [];
acc[user.role].push(user);
return acc;
}, {});
```
9. **Object Shorthand:**
```javascript
// ❌ Before: Verbose object creation
var name = 'John';
var age = 30;
var user = {
name: name,
age: age,
greet: function () {
console.log('Hello');
}
};
// ✅ After: Object shorthand
const name = 'John';
const age = 30;
const user = {
name,
age,
greet() {
console.log('Hello');
}
};
// Computed property names
const key = 'dynamicKey';
const obj = {
[key]: 'value',
[`${key}2`]: 'value2'
};
```
10. **Default Parameters:**
```javascript
// ❌ Before: Manual default values
function greet(name, greeting) {
name = name || 'Guest';
greeting = greeting || 'Hello';
return greeting + ', ' + name;
}
// ✅ After: Default parameters
function greet(name = 'Guest', greeting = 'Hello') {
return `${greeting}, ${name}`;
}
// Complex defaults
function createUser(name, options = {}) {
const { role = 'user', active = true } = options;
return { name, role, active };
}
```
11. **Modules (import/export):**
```javascript
// ❌ Before: CommonJS
var utils = require('./utils');
var helper = require('./helper');
module.exports = {
doSomething: function () {}
};
// ✅ After: ES Modules
import { utilFunction } from './utils.js';
import helper from './helper.js';
export function doSomething() {}
export default class MyClass {}
// Named exports
export const API_URL = 'https://api.example.com';
export function fetchData() {}
// Re-export
export { utilFunction } from './utils.js';
export * from './helpers.js';
```
12. **Classes:**
```javascript
// ❌ Before: Constructor functions
function User(name, email) {
this.name = name;
this.email = email;
}
User.prototype.greet = function () {
return 'Hello, ' + this.name;
};
// ✅ After: ES6 classes
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
greet() {
return `Hello, ${this.name}`;
}
// Static methods
static create(data) {
return new User(data.name, data.email);
}
// Private fields (ES2022)
#privateField = 'private';
getPrivate() {
return this.#privateField;
}
}
// Inheritance
class Admin extends User {
constructor(name, email, permissions) {
super(name, email);
this.permissions = permissions;
}
greet() {
return `${super.greet()} (Admin)`;
}
}
```
13. **Modern Iteration:**
```javascript
// ❌ Before: Traditional loops
for (var i = 0; i < array.length; i++) {
console.log(array[i]);
}
for (var key in object) {
if (object.hasOwnProperty(key)) {
console.log(key, object[key]);
}
}
// ✅ After: Modern iteration
for (const item of array) {
console.log(item);
}
for (const [key, value] of Object.entries(object)) {
console.log(key, value);
}
// Array iteration methods
array.forEach((item) => console.log(item));
// Object methods
Object.keys(obj).forEach((key) => {});
Object.values(obj).forEach((value) => {});
Object.entries(obj).forEach(([key, value]) => {});
```
14. **Complete Refactored Code:**
Provide fully refactored code with:
- Modern syntax throughout
- Async/await for all async operations
- Destructuring where appropriate
- Arrow functions
- Template literals
- Optional chaining
- Spread operators
- Array methods
- ES modules
- Comments explaining changes
Deliver production-ready modern JavaScript code that is more readable, maintainable, and follows current best practices with comprehensive refactoring and detailed explanations of improvements.