Use these guidelines to write code that’s readable, reliable, and fast. Each topic includes a short example and a Try-it editor.
JavaScript Best Practices
1) Clear Naming & Small Functions
Choose descriptive names and keep functions focused on one task.
// Bad
function doIt(a){ return a*1.18; }
// Good
function addGst(amount){ return amount*1.18; }
2) Prefer const, then let; avoid var
const prevents accidental reassignments; let when the value must change. var is function-scoped and risky.
const TAX = 0.18;
let total = 0;
total += 100 * (1+TAX);
3) Use Strict Equality (===/!==)
Avoid type-coercion surprises by using strict comparisons.
// "5" == 5 is true (coercion). Prefer strict:
console.log('5' === 5); // false
4) Null-Safety: ?. and ??
Safely access deep paths and provide defaults only for null/undefined.
const user = { profile: { name: 'Sonu' } };
const nick = user.profile?.nick ?? 'Guest';
5) Prefer Pure Functions & Guard Clauses
Pure functions are easier to test. Guard clauses reduce nested ifs.
// Guard clause
function discount(price, percent) {
if(percent <= 0) return price;
return price * (1 - percent);
}
6) Use Modern Array/Object Patterns
Prefer map/filter/reduce to manual loops; use destructuring & spread for clarity.
const prices = [100,250,60];
const withTax = prices.map(p => p*1.18);
const sum = prices.reduce((a,b) => a+b, 0);
7) Async/Await with Proper Error Handling
Wrap awaits in try...catch. For parallel tasks, use Promise.all.
async function fetchUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if(!res.ok) throw new Error('HTTP '+res.status);
return await res.json();
} catch(e) {
console.error(e); throw e;
}
}
8) DOM & Performance
Minimize reflows: batch updates, use fragments, debounce frequent events.
// Debounce a resize handler
function debounce(fn, ms) {
let t;
return (...args) => { clearTimeout(t); t = setTimeout(() => fn(...args), ms); };
}
window.addEventListener('resize', debounce(() => console.log('resized'), 200));
9) Accessibility (A11y)
Ensure interactive controls are keyboard reachable and labeled.
<button aria-label="Open menu" id="menuBtn">☰</button>
<script>
document.getElementById('menuBtn')
.addEventListener('keydown', (e) => {
if(e.key === 'Enter') { /* open */ }
});
</script>
10) Security: Avoid XSS & Unsafe Eval
Never insert untrusted HTML with innerHTML. Prefer textContent. Avoid eval.
const unsafe = '<img src=x onerror="alert(1)">';
const el = document.getElementById('out');
// el.innerHTML = unsafe; // ❌ dangerous
el.textContent = unsafe; // ✅ safe text output
11) Organize with Modules
Split code by feature. Keep one responsibility per file and use a barrel file to re-export.
// api/users.js
export async function getUser(id){ /* ... */ }
// api/index.js
export * from './users.js';
12) Testing, Linting & Formatting
Add quick assertions; use a linter/formatter to keep code consistent.
// Tiny assertion helper
function assert(cond, msg) {
if(!cond) throw new Error(msg);
}
assert(2+2 === 4, 'math broke');
13) Debugging Tips
Use DevTools: breakpoints, debugger, network tab, performance panel.
function calc(x) {
debugger; // opens DevTools if not already
return x*2;
}
calc(5);