Variable naming
const activeUsers = users.filter(u => u.isActive);const x = users.filter(u => u.a);Code gets read ten times more than it gets written. A clear name saves a comment and three trips back into the file.
const activeUsers = users.filter(u => u.isActive);const x = users.filter(u => u.a);Code gets read ten times more than it gets written. A clear name saves a comment and three trips back into the file.
function priceWithTax(item) {
let price = item.price;
if (item.onSale) price = price * 0.8;
price = price * 1.15;
return Math.round(price * 100) / 100;
}const applySale = (p, onSale) => onSale ? p * 0.8 : p;
const addTax = (p) => p * 1.15;
const round2 = (p) => Math.round(p * 100) / 100;
const priceWithTax = (item) =>
round2(addTax(applySale(item.price, item.onSale)));Each step has a name, tests on its own, and swaps without touching the rest. The pipeline tells the story with no intro paragraph needed.
const slug = (s) => s.trim().toLowerCase().replace(/\s+/g, "-");function slug(input) {
const trimmed = input.trim();
const lower = trimmed.toLowerCase();
const dashed = lower.replace(/\s+/g, "-");
return dashed;
}As long as runtime is comparable, I'd rather have three clear lines than one dense one. Each step has a name, you read it without unrolling the chain in your head.
const blockedIds = new Set(blocked);
const visible = items.filter((i) => !blockedIds.has(i.id));const visible = items.filter(
(i) => !blocked.includes(i.id),
);One extra line takes you from O(n²) to O(n). At 50 items you see nothing, at 50 000 the page stays smooth. I'm happy to add a line of code when it clearly pays off in perf.
function Profile() {
const [user, setUser] = useState(null);
useEffect(() => {
fetch("/api/me").then((r) => r.json()).then(setUser);
}, []);
return <p>{user?.name}</p>;
}function useCurrentUser() {
return useQuery({ queryKey: ["me"], queryFn: fetchMe });
}
function Profile() {
const { data: user } = useCurrentUser();
return <p>{user?.name}</p>;
}Split the what from the how. The component stays readable, the logic becomes reusable and testable. Everyone wins.
const { data, error } = await getUser(id);
if (error) return showError(error);
render(data);try {
const data = await getUser(id);
render(data);
} catch (e) {
showError(e);
}The error is part of the return type, so you can't forget it. The compiler forces you to handle it instead of letting it bubble up by accident.
function chargeCustomer(customer, amount) {
// valide le montant
if (amount <= 0) throw new Error("bad amount");
// récupère la carte par défaut
const card = customer.cards.find((c) => c.default);
// crée le paiement Stripe
return stripe.charges.create({ card: card.id, amount });
}// Charge la carte par défaut du client via Stripe.
// Détails complets de l'API: docs/api/payments.md
function chargeCustomer(customer, amount) {
if (amount <= 0) throw new Error("bad amount");
const card = customer.cards.find((c) => c.default);
return stripe.charges.create({ card: card.id, amount });
}A summary above the function gives you the context at a glance. Inline comments just repeat what the code already says. For deeper docs — a full API for example — I'd rather keep a dedicated .md file next to the code.