Vượt Qua Lối Mòn "Console.log": Làm Chủ Toàn Bộ 22 Tuyệt Chiêu Console Để Trở Thành Bậc Thầy Debug JavaScript
Chào anh em Viblo! 👋
Có một sự thật vui vẻ là: 99% anh em lập trình viên JavaScript chúng ta đều dùng chung một công cụ tối thượng để tìm bug, đó chính là console.log(). Từ việc check xem biến này có data không, API có chạy vào đây không, cho đến debug các luồng xử lý phức tạp... tất cả đều được giải quyết bằng việc "rải" console.log khắp mọi nơi.
Hồi trước mình cũng vậy, cho đến một ngày console của trình duyệt biến thành một "bãi rác" đúng nghĩa với hàng trăm dòng log vô danh, không biết dòng nào do hàm nào sinh ra, dòng nào chạy trước dòng nào chạy sau. Lúc đó, mình mới chịu mò vào tài liệu và nhận ra: Đối tượng console trong JavaScript mạnh hơn chúng ta tưởng rất nhiều. Nó cung cấp tới hơn 20 phương thức xịn sò để chúng ta phân loại, định dạng và đo đạc hiệu năng hệ thống ngay tại tab Console của DevTools.
Hôm nay, mình sẽ cùng anh em mổ xẻ toàn bộ các phương thức console từ cơ bản đến nâng cao để nâng cấp trình độ debug của anh em lên một tầm cao mới nhé!
Nhóm 1: Phân Loại Log Theo Cấp Độ (Logging Levels) Thay vì cái gì cũng console.log, trình duyệt hỗ trợ chúng ta phân loại mức độ nghiêm trọng của log. Điều này giúp anh em có thể dùng bộ lọc (Filter) của DevTools để ẩn/hiện log cực kỳ tiện lợi.
- console.log(): Trùm cuối, dùng để in ra thông tin thông thường.
- console.info(): Tương tự như log(), nhưng mang tính chất thông báo (ở một số trình duyệt nó sẽ có thêm biểu tượng chữ i nhỏ).
- console.warn(): In ra cảnh báo màu vàng. Dữ liệu vẫn chạy được nhưng có nguy cơ tiềm ẩn lỗi
- console.error(): In ra lỗi màu đỏ chót, kèm theo cả Stack Trace (dấu vết các hàm đã gọi) để anh em biết lỗi sinh ra từ đâu.
- console.debug(): Dùng cho mục đích debug nội bộ. Nó sẽ bị ẩn mặc định trên DevTools, chỉ khi nào anh em bật chế độ lọc Verbose (hoặc All levels) thì nó mới hiện lên. Cực kỳ thích hợp để viết log ẩn khi phát triển.
Nhóm 2: "Trực Quan Hóa" Dữ Liệu Phức Tạp Nỗi đau lớn nhất khi log một Object hoặc Array lớn là cấu trúc của nó rất khó nhìn. Nhóm hàm này sinh ra là để giải quyết việc đó.
console.table() — Cứu cánh cho Array và Object Nếu anh em có một mảng các Object, thay vì click mỏi tay để mở từng cái xem dữ liệu, hãy dùng console.table(). Nó sẽ biến mảng đó thành một cái bảng dữ liệu (Table) siêu đẹp, có thể click vào tiêu đề để sắp xếp (sort) luôn.
const users = [
{ id: 1, name: 'Hoang', role: 'Admin' },
{ id: 2, name: 'Tuấn', role: 'Dev' }
];
console.table(users);
console.dir() và console.dirxml() — Nhìn thấu cấu trúc
- console.dir(): Ép trình duyệt phải hiển thị đối tượng dưới dạng một danh sách các thuộc tính JavaScript thuần túy (JSON-like tree). Rất hữu ích khi anh em muốn soi các thuộc tính ẩn của một DOM element.
- console.dirxml(): Ngược lại, nó sẽ hiển thị đối tượng dưới dạng cây cấu trúc XML/HTML (giống như khi anh em soi trong tab Elements).
Nhóm 3: Gom Nhóm Log Cho Gọn Gàng Khi một hàm gọi nhiều hàm con và mỗi hàm lại in ra log, màn hình console sẽ bị rối. Hãy dùng nhóm hàm này để "quy hoạch" chúng lại.
- console.group('Tên Nhóm'): Bắt đầu gom nhóm các dòng log tiếp theo vào một khối và thụt lề vào trong.
- console.groupCollapsed('Tên Nhóm'): Giống như group(), nhưng mặc định khối này sẽ bị đóng lại, khi nào dev tò mò click vào thì nó mới xổ ra.
- console.groupEnd(): Đánh dấu kết thúc nhóm hiện tại.
console.group('Luồng Thanh Toán');
console.log('Bước 1: Check giỏ hàng');
console.log('Bước 2: Trừ tiền');
console.groupEnd();
Nhóm 4: Đếm Số Lần Thực Thi (Counting) Nhiều khi anh em làm React/Vue, muốn biết một Component bị re-render bao nhiêu lần, hoặc một hàm vòng lặp bị chạy bao nhiêu bận, thay vì tạo biến đếm let count = 0 thủ công, hãy dùng:
- console.count('Nhãn đếm'): Mỗi lần code chạy qua dòng này, nó sẽ tự động tăng số đếm của 'Nhãn đếm' lên 1 và in ra.
- console.countReset('Nhãn đếm'): Reset số đếm của nhãn đó về lại bằng 0.
Nhóm 5: Đo Đạc Hiệu Năng (Timing & Profiling) Đừng dùng new Date() hay performance.now() để trừ thời gian đo tốc độ chạy của code nữa anh em ơi, console có sẵn bộ đo stopwatch siêu xịn:
- console.time('Timer_Name'): Bấm giờ, bắt đầu tính thời gian cho nhãn Timer_Name.
- console.timeLog('Timer_Name'): In ra thời gian đã trôi qua kể từ lúc bấm giờ (dùng để check các mốc ở giữa chặng).
- console.timeEnd('Timer_Name'): Dừng đồng hồ bấm giờ và in ra tổng thời gian chạy (bằng mili-giây).
- console.timeStamp('Marker_Name'): Thêm một điểm đánh dấu (marker) vào tab Performance của trình duyệt. Nó giúp anh em đối chiếu xem lúc câu lệnh này chạy thì biểu đồ CPU/RAM của trình duyệt đang biến động như thế nào.
- console.profile('Profile_Name') & console.profileEnd(): Kích hoạt bộ phân tích CPU (JavaScript Profiler) ngầm của trình duyệt. Nó sẽ ghi lại chi tiết xem hàm nào ngốn nhiều tài nguyên nhất trong khoảng giữa 2 lệnh này và hiển thị kết quả trong tab Profiler.
Nhóm 6: Kiểm Tra Điều Kiện Và Dấu Vết (Testing & Tracing)
- console.assert(expression, message): Đây là kỹ thuật "Conditional Logging" cực hay. Dòng message sẽ chỉ được in ra nếu expression trả về kết quả là FALSE. Thay vì viết if (!valid) console.error('Lỗi rồi'), anh em chỉ cần: console.assert(valid, 'Lỗi rồi').
- console.trace(): In ra toàn bộ Stack Trace tại vị trí nó được gọi. Hàm này cực kỳ quyền lực khi anh em làm việc với một source code bự, thấy một hàm tự dưng bị kích hoạt mà không biết "ông thần" nào từ file nào đã gọi nó. console.trace() sẽ chỉ đích danh sơ đồ tổ chức cuộc gọi đó cho bạn.
Nhóm 7: Dọn Dẹp Chiến Trường
- console.clear(): Xóa sạch bách mọi dòng log đang có trên màn hình console, trả lại một không gian trắng trẻo, sạch sẽ để anh em bắt đầu một phiên debug mới.
Bảng Tổng Hợp Tiện Tra Cứu
| Column 1 | Column 2 | Column 3 |
|---|---|---|
| log, info, debug | In thông tin thông thường / Ẩn debug | Log luồng chạy cơ bản |
| warn, error | Cảnh báo / Báo lỗi đỏ | Bắt lỗi trong catch(err) |
| table | Biến mảng/object thành bảng dữ liệu | Xem danh sách data từ API |
| dir, dirxml | Xem thuộc tính đối tượng / Cây DOM | Debug DOM Element sâu |
| group, groupEnd | Gom nhóm log thu gọn | Khử rối cho console |
| count, countReset | Tự động đếm số lần chạy | Check re-render component |
| time, timeEnd | Đo thời gian chạy bằng mili-giây | Tối ưu thuật toán, đo tốc độ hàm |
| assert | Chỉ log khi điều kiện bị SAI | Thay thế cho các câu lệnh if check lỗi |
| trace | Tìm dấu vết các hàm gọi nhau | Tìm thủ phạm gọi hàm ngầm |
Kinh nghiệm xương máu trước khi lên Production
Các phương thức console vô cùng hữu ích trong quá trình làm Local (Development). Tuy nhiên, hãy luôn dọn dẹp hoặc cấu hình tắt toàn bộ log trước khi Build lên Production.
Việc lạm dụng console.log ở môi trường thực tế không những làm giảm hiệu năng hệ thống của khách hàng (vì trình duyệt phải tốn tài nguyên render log liên tục), mà nguy hiểm hơn, nó có thể vô tình lộ thông tin nhạy cảm (như Token, Payload API, cấu trúc DB) cho hacker xem trộm qua tab Console. Anh em có thể dùng các plugin như terser hoặc cấu hình Webpack/Vite để tự động xóa sạch các lệnh console.* khi build sản phẩm nhé.
Hy vọng bài tổng hợp này giúp anh em có thêm nhiều vũ khí hạng nặng để "vả" bug một cách chuyên nghiệp hơn. Nếu thấy hữu ích, hãy để lại 1 upvote cho mình nhé! Happy Coding! 🚀💻
All rights reserved