Use console methods effectively, read stack traces, and step through code in the browser's Sources panel. Learn to identify and fix memory leaks and performance issues.
Why: the console is your primary debugging tool. Beyond console.log, there are methods for tables, timing, grouping, and assertions.
// Basic logging
console.log('log');
console.warn('warn — shows in yellow');
console.error('error — shows in red');
console.info('info');
// Structured output
const users = [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }];
console.table(users);
// Grouping
console.group('User details');
console.log('name: Alice');
console.log('role: admin');
console.groupEnd();
// Timing
console.time('loop');
let sum = 0;
for (let i = 0; i < 1e6; i++) sum += i;
console.timeEnd('loop'); // prints elapsed ms
// Assertion — only logs if condition is false
console.assert(1 === 1, 'this never prints');
console.assert(1 === 2, 'assertion failed: 1 !== 2');
// Count calls
for (let i = 0; i < 3; i++) console.count('iteration');Why: beyond console.log, the debugger statement pauses execution in DevTools Sources panel. Understanding stack traces helps locate errors fast.
// debugger — pauses when DevTools is open
function processNumbers(arr) {
// debugger; // uncomment, open DevTools, then run
return arr
.filter(n => n > 0)
.map(n => n * 2)
.reduce((acc, n) => acc + n, 0);
}
console.log(processNumbers([1, -2, 3, -4, 5])); // 18
// Reading a stack trace
function c() { throw new Error('something went wrong'); }
function b() { c(); }
function a() { b(); }
try {
a();
} catch (e) {
console.log(e.message);
// e.stack shows the full call chain: c → b → a
const top3 = e.stack.split('\n').slice(0, 3).join('\n');
console.log(top3);
}
// Memory leak: forgotten event listeners
// BAD: element.addEventListener('click', () => { ... });
// GOOD: store the handler ref and call removeEventListener when done