// Uses ES6+ features and modern JavaScript patterns
# Modern JavaScript Practices
Use modern JavaScript features for cleaner, more maintainable code.
## Use const/let, Not var
```javascript
// Bad
var name = 'Alice';
var age = 30;
// Good
const name = 'Alice';
let age = 30;
```
## Use Arrow Functions
```javascript
// Bad
function add(a, b) {
return a + b;
}
// Good
const add = (a, b) => a + b;
// For arrays
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
```
## Use Template Literals
```javascript
const name = 'Alice';
const age = 30;
// Bad
const message = 'My name is ' + name + ' and I am ' + age + ' years old';
// Good
const message = `My name is ${name} and I am ${age} years old`;
// Multi-line strings
const html = `
<div>
<h1>${title}</h1>
<p>${content}</p>
</div>
`;
```
## Use Destructuring
```javascript
// Object destructuring
const user = { name: 'Alice', age: 30, email: 'alice@example.com' };
// Bad
const name = user.name;
const age = user.age;
// Good
const { name, age } = user;
// With renaming
const { name: userName, age: userAge } = user;
// Array destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// Swap variables
[a, b] = [b, a];
```
## Use Spread Operator
```javascript
// Arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// Bad
const combined = arr1.concat(arr2);
// Good
const combined = [...arr1, ...arr2];
// Objects
const user = { name: 'Alice', age: 30 };
// Bad
const updatedUser = Object.assign({}, user, { age: 31 });
// Good
const updatedUser = { ...user, age: 31 };
// Function arguments
const numbers = [1, 2, 3, 4, 5];
Math.max(...numbers);
```
## Use Default Parameters
```javascript
// Bad
function greet(name) {
name = name || 'Guest';
return `Hello, ${name}`;
}
// Good
function greet(name = 'Guest') {
return `Hello, ${name}`;
}
```
## Use Optional Chaining
```javascript
// Bad
const city = user && user.address && user.address.city;
// Good
const city = user?.address?.city;
// With arrays
const firstItem = items?.[0];
// With functions
const result = obj.method?.();
```
## Use Nullish Coalescing
```javascript
// Bad - treats 0, false, '' as falsy
const value = userValue || 'default';
// Good - only null/undefined trigger default
const value = userValue ?? 'default';
// Example
const count = 0;
console.log(count || 10); // 10 (wrong!)
console.log(count ?? 10); // 0 (correct!)
```
## Use Array Methods
```javascript
const numbers = [1, 2, 3, 4, 5];
// map - transform each element
const doubled = numbers.map(n => n * 2);
// filter - keep matching elements
const evens = numbers.filter(n => n % 2 === 0);
// reduce - accumulate to single value
const sum = numbers.reduce((acc, n) => acc + n, 0);
// find - get first match
const firstEven = numbers.find(n => n % 2 === 0);
// some - check if any match
const hasEven = numbers.some(n => n % 2 === 0);
// every - check if all match
const allPositive = numbers.every(n => n > 0);
```
## Use Async/Await
```javascript
// Bad - callback hell
fetchUser(userId, (user) => {
fetchPosts(user.id, (posts) => {
fetchComments(posts[0].id, (comments) => {
console.log(comments);
});
});
});
// Better - promises
fetchUser(userId)
.then(user => fetchPosts(user.id))
.then(posts => fetchComments(posts[0].id))
.then(comments => console.log(comments));
// Best - async/await
async function getUserComments(userId) {
const user = await fetchUser(userId);
const posts = await fetchPosts(user.id);
const comments = await fetchComments(posts[0].id);
return comments;
}
// Error handling
async function getData() {
try {
const data = await fetchData();
return data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
```
## Use Object/Array Shorthand
```javascript
const name = 'Alice';
const age = 30;
// Bad
const user = {
name: name,
age: age,
greet: function() {
return 'Hello';
}
};
// Good
const user = {
name,
age,
greet() {
return 'Hello';
}
};
```
## Use Set for Unique Values
```javascript
// Bad
const unique = array.filter((v, i, a) => a.indexOf(v) === i);
// Good
const unique = [...new Set(array)];
// Check existence
const set = new Set([1, 2, 3]);
set.has(2); // true
set.add(4);
set.delete(1);
```
## Use Map for Key-Value Pairs
```javascript
// When keys aren't strings or need order
const map = new Map();
map.set('key1', 'value1');
map.set(123, 'numeric key');
map.set({ obj: true }, 'object key');
map.get('key1'); // 'value1'
map.has('key1'); // true
map.delete('key1');
// Iterate
for (const [key, value] of map) {
console.log(key, value);
}
```
## Use Modules
```javascript
// export.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export default class Calculator {}
// import.js
import Calculator, { PI, add } from './export.js';
import * as math from './math.js';
```
## Avoid Modifying Parameters
```javascript
// Bad
function addItem(array, item) {
array.push(item); // Mutates original
return array;
}
// Good
function addItem(array, item) {
return [...array, item]; // Returns new array
}
```
## Use Early Returns
```javascript
// Bad
function processUser(user) {
if (user) {
if (user.active) {
if (user.email) {
return sendEmail(user.email);
}
}
}
}
// Good
function processUser(user) {
if (!user) return;
if (!user.active) return;
if (!user.email) return;
return sendEmail(user.email);
}
```
Modern JavaScript is more concise, readable, and less error-prone.6 matches