Hey there! After years of coding JavaScript, I've collected these practical tricks that have made my life easier. Each one comes with a simple explanation and example so you can see exactly how it works and why it's useful.
1. Rename variables while destructuring
When you need to extract properties from an object but want to use different variable names:
const user = { name: 'Alice', age: 25 };
const { name: userName, age: userAge } = user;
console.log(userName); // Alice
console.log(userAge); // 25
Why it's useful: Prevents naming conflicts and makes your code more readable when working with multiple objects.
2. Optional chaining for functions
Check if a function exists before calling it to prevent errors:
const user = {
getName: () => 'Alice',
// getAge doesn't exist
};
console.log(user.getName?.()); // Alice
console.log(user.getAge?.()); // undefined instead of error
Why it's useful: Prevents your app from crashing when a function doesn't exist.
3. Default assignment with ||=
Assign a value to a variable only if it's currently undefined, null, or falsy:
let count; // undefined
count ||= 10;
console.log(count); // 10
count = 0; // falsy value
count ||= 5;
console.log(count); // 5 (because 0 is falsy)
Why it's useful: Provides default values without writing longer if statements.
4. Convert nodelist to array
Transform DOM element collections into real arrays to use array methods:
// When you select multiple elements
const divs = document.querySelectorAll('div'); // This is a NodeList, not an Array
const divArray = [...divs]; // Now it's a real Array
// Now you can use array methods
divArray.map(div => div.classList.add('highlighted'));
Why it's useful: NodeLists don't have all Array methods, so converting them lets you use map, filter, reduce, etc.
5. Destructuring with default values
Extract properties from objects with fallback values if they don't exist:
const user = { name: 'Alice' }; // No age property
const { name, age = 25 } = user;
console.log(name); // Alice
console.log(age); // 25 (default value)
Why it's useful: Handles missing data gracefully without extra code.
6. Remove falsy values from arrays
Clean up arrays by removing all falsy values (false, null, 0, "", undefined, NaN):
const messyArray = [0, 'hello', null, 42, false, '', undefined, 'world'];
const cleanArray = messyArray.filter(Boolean);
console.log(cleanArray); // ["hello", 42, "world"]
Why it's useful: Simplifies data cleaning with just one line of code.
7. Sort arrays of objects
Sort an array of objects based on any property:
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 20 },
{ name: 'Charlie', age: 30 }
];
// Sort by age (youngest to oldest)
users.sort((a, b) => a.age - b.age);
console.log(users);
// Output: [{ name: 'Bob', age: 20 }, { name: 'Alice', age: 25 }, { name: 'Charlie', age: 30 }]
Why it's useful: Organizes data for display or processing.
8. Dynamic imports for lazy loading
Load JavaScript modules only when needed:
// Instead of importing everything at the start
const loadChartModule = async () => {
// Only loads when user clicks "Show Chart" button
const chartModule = await import('./charts.js');
chartModule.createChart();
};
document.getElementById('showChart').addEventListener('click', loadChartModule);
Why it's useful: Improves page load speed by loading code only when necessary.
9. Object destructuring in function parameters
Set default values for object parameters in functions:
function createUser({ name = 'Guest', age = 18, role = 'user' } = {}) {
console.log(`Created ${role} ${name}, age ${age}`);
return { name, age, role };
}
createUser(); // "Created user Guest, age 18"
createUser({ name: 'Alice' }); // "Created user Alice, age 18"
createUser({ name: 'Bob', age: 25, role: 'admin' }); // "Created admin Bob, age 25"
Why it's useful: Makes function parameters more flexible and provides sensible defaults.
10. Safe object copying
Create a copy of an object without affecting the original:
const original = { a: 1, b: 2, c: { value: 3 } };
const copy = Object.assign({}, original);
copy.a = 100;
console.log(original.a); // Still 1
console.log(copy.a); // 100
// Note: This is a shallow copy
copy.c.value = 300;
console.log(original.c.value); // Also 300 (nested objects are referenced, not copied)
Why it's useful: Prevents accidental changes to original data when working with copies.
11. Memoize functions for performance
Cache results of expensive function calls:
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (!cache[key]) {
console.log("Calculating result...");
cache[key] = fn(...args);
} else {
console.log("Returning from cache");
}
return cache[key];
};
}
// Example with a slow function
function calculateFactorial(n) {
if (n <= 1) return 1;
return n * calculateFactorial(n - 1);
}
const fastFactorial = memoize(calculateFactorial);
console.log(fastFactorial(5)); // Calculating result... 120
console.log(fastFactorial(5)); // Returning from cache 120
Why it's useful: Dramatically speeds up repeated calculations with the same inputs.
12. Group array items by property
Organize array items into groups based on a property:
const people = [
{ name: 'Alice', department: 'Engineering' },
{ name: 'Bob', department: 'Sales' },
{ name: 'Charlie', department: 'Engineering' },
{ name: 'Dave', department: 'Marketing' }
];
const byDepartment = people.reduce((groups, person) => {
// Create the array for this department if it doesn't exist
if (!groups[person.department]) {
groups[person.department] = [];
}
// Add the person to their department group
groups[person.department].push(person);
return groups;
}, {});
console.log(byDepartment);
/* Output:
{
Engineering: [
{ name: 'Alice', department: 'Engineering' },
{ name: 'Charlie', department: 'Engineering' }
],
Sales: [{ name: 'Bob', department: 'Sales' }],
Marketing: [{ name: 'Dave', department: 'Marketing' }]
}
*/
Why it's useful: Perfect for organizing data for reports, charts, or UI components.
13. Flatten nested arrays
Convert a multi-level array into a simple flat array:
const deeplyNested = [1, [2, [3, [4, [5]]]]];
// Flatten all levels
const flattened = deeplyNested.flat(Infinity);
console.log(flattened); // [1, 2, 3, 4, 5]
// Flatten just one level
const partiallyFlattened = deeplyNested.flat(1);
console.log(partiallyFlattened); // [1, 2, [3, [4, [5]]]]
Why it's useful: Simplifies processing of complex nested data structures.
14. Toggle boolean states
Easily switch a boolean value between true and false:
let menuOpen = false;
function toggleMenu() {
menuOpen = !menuOpen;
console.log(menuOpen ? "Menu is open" : "Menu is closed");
}
toggleMenu(); // "Menu is open"
toggleMenu(); // "Menu is closed"
Why it's useful: Common pattern for toggle features like dark mode, menu visibility, etc.
15. Combine multiple arrays
Merge several arrays into one:
const fruits = ['apple', 'banana'];
const vegetables = ['carrot', 'potato'];
const meats = ['chicken', 'beef'];
// Method 1: concat
const foodItems = fruits.concat(vegetables, meats);
console.log(foodItems);
// ['apple', 'banana', 'carrot', 'potato', 'chicken', 'beef']
// Method 2: spread operator
const allFoods = [...fruits, ...vegetables, ...meats];
console.log(allFoods);
// ['apple', 'banana', 'carrot', 'potato', 'chicken', 'beef']
Why it's useful: Combines data from multiple sources without changing the original arrays.
16. Process async operations in sequence
Handle multiple async operations one after another:
async function processTasks() {
const tasks = ['task1', 'task2', 'task3'];
// Process each task in order
for (const task of tasks) {
console.log(`Starting ${task}`);
// Simulate async operation
const result = await fetchTaskData(task);
console.log(`Completed ${task} with result: ${result}`);
}
console.log('All tasks completed');
}
// Helper function that returns a promise
async function fetchTaskData(task) {
// Simulate API call
return new Promise(resolve => {
setTimeout(() => resolve(`data for ${task}`), 1000);
});
}
processTasks();
Why it's useful: Ensures operations happen in the correct order without complex callback chains.
17. Access array items from the end
Get items from the end of an array without calculating the length:
const colors = ['red', 'green', 'blue', 'yellow', 'purple'];
console.log(colors.at(-1)); // 'purple' (last item)
console.log(colors.at(-2)); // 'yellow' (second-to-last item)
console.log(colors.at(-3)); // 'blue' (third-to-last item)
// This is more convenient than:
console.log(colors[colors.length - 1]); // 'purple'
Why it's useful: Simplifies access to items relative to the end of an array.
18. Format dates consistently
Display dates in a user-friendly format across different locales:
const now = new Date();
// Full date format
const fullDate = new Intl.DateTimeFormat('en-US', {
dateStyle: 'full',
timeStyle: 'long'
}).format(now);
console.log(fullDate); // "Monday, January 1, 2024 at 12:00:00 PM GMT+0"
// Short date format
const shortDate = new Intl.DateTimeFormat('en-US', {
dateStyle: 'short'
}).format(now);
console.log(shortDate); // "1/1/24"
// Different locale
const frenchDate = new Intl.DateTimeFormat('fr-FR', {
dateStyle: 'full'
}).format(now);
console.log(frenchDate); // "lundi 1 janvier 2024"
Why it's useful: Provides consistent date formatting across your application with support for different languages.
19. Round numbers precisely
Round numbers to a specific decimal place:
const price = 19.99;
const tax = 1.7463;
const total = price + tax;
// Round to 2 decimal places
const roundedTotal = Math.round(total * 100) / 100;
console.log(roundedTotal); // 21.74
// Format as currency
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
});
console.log(formatter.format(roundedTotal)); // "$21.74"
Why it's useful: Ensures consistent number display in financial calculations and user interfaces.
20. Convert array-like objects to real arrays
Turn array-like objects (like function arguments) into actual arrays:
function addAllNumbers() {
// arguments is an array-like object, not a real array
const numbers = Array.from(arguments);
// Now we can use array methods
return numbers.reduce((sum, num) => sum + num, 0);
}
console.log(addAllNumbers(1, 2, 3, 4, 5)); // 15
Why it's useful: Allows you to use array methods on objects that look like arrays but aren't.
I hope these JavaScript tricks make your coding life easier! Each one has saved me time and headaches in real projects. Try them out in your next project and see how they can improve your code.