LearningJavaScript TutorialDebugging & Best Practices
CHAPTER 17 · QUALITY & DEBUGGING

JavaScript Debugging & Best Practices

Good JavaScript sirf “chalne wala code” nahi hota. Is chapter me bugs ko systematically find karna, DevTools use karna, useful errors handle karna aur readable, secure, accessible, maintainable code likhna practice karenge.

English + Hinglish52 min readPractice included

Debugging mindset

Debugging means evidence collect karke problem ka actual cause find karna. Random changes karna debugging nahi hota.

Hinglish Explanation

Bug aaye to pehle reproduce karo, phir exact input/state note karo, smallest failing part identify karo, evidence dekho aur tab fix test karo. “Shayad ye hoga” se zyada useful hai “console/network/stack kya dikha raha hai?”

1. Reproduce before fixing

A bug that cannot be reproduced is difficult to verify. Record the steps, expected result and actual result.

  • Problem kis page/action par hoti hai?
  • Kaunsa input diya gaya?
  • Every time hoti hai ya occasionally?
  • Console me error hai?
  • Network request fail hui?
  • Expected behavior exactly kya tha?

Common JavaScript error types

Error message ka type useful clue deta hai.

errors.jsJS
// ReferenceError
console.log(notDeclared);

// TypeError
const user = null;
console.log(user.name);

// SyntaxError example idea:
// invalid JavaScript syntax prevents parsing
  • SyntaxError: code grammar invalid hai.
  • ReferenceError: identifier available nahi hai.
  • TypeError: value par unsupported operation/property access hua.
  • RangeError: value allowed range ke bahar hai in certain operations.

Read the message and stack trace

Error message ko skip mat karo. Stack trace often file, line and function call path show karta hai.

Useful habit: Stack trace me apne application code ki first relevant line se start karo, especially jab framework/library internals bhi listed hon.

Console tools

Console sirf console.log() ke liye nahi hai.

console-tools.jsJS
console.log("student", student);
console.table(students);
console.warn("Deprecated path used");
console.error("Could not save progress");
console.assert(score >= 0, "Score should not be negative");
console.time("render");
renderList(items);
console.timeEnd("render");

Debug logging ko meaningful labels do. Production code me noisy temporary logs remove karo when they are no longer useful.

Breakpoints in DevTools

Browser DevTools Sources panel me breakpoint code execution ko chosen line par pause karta hai. Paused state me variables, scope, call stack and expressions inspect kar sakte ho.

  • Line breakpoint — specific line par pause.
  • Conditional breakpoint — condition true hone par pause.
  • Event listener breakpoint — click, submit etc. par pause.
  • Exception pause — thrown exceptions par pause.

The debugger statement

DevTools open hone par debugger; statement execution pause kar sakta hai.

debugger.jsJS
function calculateTotal(items) {
  debugger;
  return items.reduce((sum, item) => sum + item.price, 0);
}
Cleanup: Temporary debugger statements commit karne se pehle remove karo unless intentionally needed.

Step through code

Paused execution me DevTools usually step over, step into and step out controls deta hai.

  • Step over: current line execute karo without entering called function.
  • Step into: called function ke andar jao.
  • Step out: current function complete karke caller par return.

Inspect scope and values

Breakpoint par local variables, closure values and globals inspect karo. Watch expressions se important expression repeatedly evaluate ki ja sakti hai.

Debugging trick

“Variable wrong kyun hai?” ka answer guess mat karo. Execution ko us line se pehle pause karke dekho variable kab wrong hota hai.

Network debugging

Fetch/API bugs ke liye Network panel essential hai. URL, method, status, headers, payload, response and timing inspect karo.

Separate problems: JavaScript bug, server HTTP error, invalid JSON, auth failure and CORS problem alag causes hain. Sabko “fetch broken” mat bolo.

DOM and event debugging

Elements panel se confirm karo ki element actually exist karta hai, expected class/attribute laga hai aur event target wahi hai jo tum expect kar rahe ho.

guard-dom.jsJS
const button = document.querySelector("#save-button");

if (!button) {
  throw new Error("Save button was not found");
}

button.addEventListener("click", saveProgress);

try/catch: use where recovery is possible

try/catch thrown errors handle kar sakta hai, but every line ko blindly wrap karna good practice nahi hai.

try-catch.jsJS
try {
  const data = JSON.parse(rawText);
  showData(data);
} catch (error) {
  console.error("Invalid JSON", error);
  showMessage("Data could not be read.");
}

Catch block me decide karo: recover, user ko message do, log karo, ya error ko rethrow karo.

Throw useful errors

Invalid state ko silently continue karne ke bajay clear error useful ho sakta hai.

throw.jsJS
function calculatePercentage(score, total) {
  if (total <= 0) {
    throw new RangeError("total must be greater than zero");
  }

  return (score / total) * 100;
}
Message quality: “Something went wrong” developer debugging ke liye weak message hai. State what was invalid and what was expected.

finally for cleanup

finally success ya failure dono cases ke baad cleanup ke liye useful hai.

finally.jsJS
showLoading();

try {
  await saveProgress();
} catch (error) {
  showError("Could not save progress");
} finally {
  hideLoading();
}

Reduce the problem

Large page fail ho rahi ho to smallest failing input/function isolate karo. Smaller reproduction cause ko visible banata hai.

Temporarily unrelated code remove/disable karke test karo, but final fix ko full app flow me verify zaroor karo.

Clear naming

Names code ki first documentation hoti hain.

naming.jsJS
// Weak
const x = users.filter(u => u.a);

// Clearer
const activeUsers = users.filter(user => user.isActive);

Variables nouns, boolean values meaningful yes/no names, aur functions action-oriented names use kar sakte hain.

Small focused functions

Function ka one clear responsibility debugging aur testing easier banata hai.

focused.jsJS
function normalizeName(value) {
  return value.trim();
}

function isValidName(value) {
  return value.length >= 2;
}

“Small” ka fixed line count nahi hai; goal coherent responsibility hai.

Guard clauses

Invalid cases early return karke deep nesting reduce ki ja sakti hai.

guard.jsJS
function getDiscount(user) {
  if (!user) return 0;
  if (!user.isMember) return 0;
  if (user.orders < 5) return 0;

  return 10;
}

Prefer predictable bindings

const by default use karo; reassignment required ho to let. Unnecessary mutable variables reasoning harder bana sakte hain.

Remember: const object contents ko deeply immutable nahi banata.

Avoid unnecessary globals

Global state unrelated code ke through accidentally change ho sakti hai. Modules, functions and clear data flow dependencies ko easier to trace banate hain.

Organize by responsibility

Modules ko meaningful responsibility ke around split karo: API client, rendering helpers, validation, state management, etc. Har tiny function ko separate file banana bhi unnecessary fragmentation ho sakta hai.

Comments explain why, not obvious what

comments.jsJS
// Keep previous result visible during refresh to avoid layout jump.
await refreshCourses();

Outdated comments misleading hote hain. Code change ke saath comments bhi update karo.

Consistent formatting

Consistent indentation, spacing and line breaks code review easier banate hain. Teams formatter use kar sakti hain so style debates automated ho jayein.

Linting

A linter suspicious patterns aur style/code-quality issues detect kar sakta hai before runtime. Lint rules team/project ke context me choose karo; warnings ko blindly disable mat karo.

Async code best practices

  • Promise ko return/await karna mat bhoolo.
  • Independent work ko unnecessarily sequential mat banao.
  • Rejected Promises ke liye intentional error handling rakho.
  • Loading/error/empty UI states plan karo.
  • Stale requests ko cancel/ignore karo where correctness requires it.
  • HTTP status explicitly check karo.

DOM best practices

  • Repeated selectors ko appropriate scope me cache karo.
  • User/API plain text ke liye textContent prefer karo.
  • Large repeated DOM changes ko unnecessary loops me avoid karo.
  • Event delegation use karo when many similar dynamic children exist.
  • Removed components ke long-lived listeners/timers cleanup karo when needed.

Performance: measure first

Premature optimization code ko complex bana sakti hai. Pehle real bottleneck measure karo using Performance tools, timings or profiling, then targeted optimization karo.

Rule: Readable correct code first. Optimize measured hot paths, not assumptions.

Accessibility is part of code quality

Interactive JavaScript keyboard, focus and screen reader behavior ko break nahi karna chahiye.

  • Native buttons/inputs ko custom div controls se prefer karo.
  • Keyboard interaction test karo.
  • Validation errors ko text me explain karo.
  • Async updates ke liye appropriate live-region strategy consider karo.
  • Modal/menu open-close par focus behavior intentionally manage karo.
  • Color alone ko state signal mat banao.

Security habits

  • Untrusted strings ko innerHTML me directly inject mat karo.
  • Frontend bundle me secret API keys mat store karo.
  • Client validation ko security boundary mat samjho.
  • Authorization server par enforce honi chahiye.
  • External data ko expected shape/type ke against validate karo.

Test behavior, not assumptions

Manual testing se start kar sakte ho, but important logic ke repeatable tests long-term confidence improve karte hain. Pure functions easiest starting point hote hain.

manual-test.jsJS
console.assert(isValidName("Aman") === true);
console.assert(isValidName("A") === false);

Real projects automated test tools use kar sakte hain; core idea expected input-output behavior ko repeatably verify karna hai.

Before committing code

  • Temporary logs/debugger statements remove kiye?
  • Errors intentionally handle ho rahe hain?
  • Variable/function names clear hain?
  • Dead/unreachable code remove hua?
  • Keyboard/focus behavior test hua?
  • Network failure/empty state test hua?
  • Secrets accidentally source me to nahi?
  • Console me unexpected errors/warnings to nahi?

Common beginner mistakes

  • Error message padhe bina random code change karna.
  • Huge number of console.log() add karke signal lose karna.
  • try/catch me error silently swallow karna.
  • Every problem ko catch karke root cause hide karna.
  • Variable names x, data1, temp2 everywhere use karna.
  • Long function me unrelated responsibilities mix karna.
  • Performance optimize karna without measurement.
  • Happy path test karke errors/empty states skip karna.
  • Accessibility ko final polish samajhna.
  • Client-side code me secret credential rakhna.

Chapter checklist

  • Error message aur stack trace read kar sakte ho?
  • Breakpoints and step controls use karne ka idea clear hai?
  • Network panel se API issue inspect kar sakte ho?
  • try/catch/finally ko intentional recovery/cleanup ke liye use kar sakte ho?
  • Useful errors throw kar sakte ho?
  • Guard clauses and focused functions se code simplify kar sakte ho?
  • Performance ko measure-first mindset se approach kar sakte ho?
  • Accessibility and security ko code quality ka part samajhte ho?

Practice Task — Debug & Improve a Learning Dashboard

Ek intentionally imperfect JavaScript page lo aur systematic audit karo.

  1. Ek reproducible bug likho: steps, expected result, actual result.
  2. Console error message aur stack line identify karo.
  3. Breakpoint lagakar wrong variable value ka first point find karo.
  4. debugger statement temporarily use karke scope inspect karo, then remove karo.
  5. Network panel me ek failed request inspect karo.
  6. response.ok missing ho to fix karo.
  7. Ek vague error message ko actionable message me improve karo.
  8. Deep nested condition ko guard clauses se simplify karo.
  9. Ek long function ko 2–3 focused functions me split karo.
  10. Weak variable names improve karo.
  11. Untrusted text rendering me innerHTML ko safe textContent pattern se replace karo.
  12. Loading, empty and error UI states verify karo.
  13. Keyboard-only navigation se interactive controls test karo.
  14. Temporary console/debug code cleanup karo.
  15. Final review checklist run karke console ko unexpected errors se clean rakho.