使用浏览器开发者工具调试。
// 打开开发者工具
// Windows: F12 或 Ctrl+Shift+I
// Mac: Cmd+Option+I
// Elements面板:查看和编辑DOM
// Console面板:执行JavaScript
// Sources面板:调试源代码
// Network面板:查看网络请求
// Performance面板:性能分析
// Memory面板:内存分析
// Application面板:存储和应用
// 基本输出
console.log("普通日志");
console.info("信息日志");
console.warn("警告日志");
console.error("错误日志");
// 格式化输出
console.log("用户: %s, 年龄: %d", "东巴文", 25);
// 对象输出
const user = { name: "东巴文", age: 25 };
console.log(user);
console.table(user);
console.dir(user);
// 分组输出
console.group("用户信息");
console.log("姓名:", user.name);
console.log("年龄:", user.age);
console.groupEnd();
// 计时
console.time("操作");
for (let i = 0; i < 1000000; i++) {}
console.timeEnd("操作"); // 操作: 2.5ms
// 计数
console.count("点击");
console.count("点击");
console.count("点击"); // 点击: 3
// 断言
console.assert(1 === 2, "断言失败");
// 清空控制台
console.clear();
// 堆栈跟踪
function a() { b(); }
function b() { c(); }
function c() { console.trace(); }
a();
使用断点暂停代码执行。
function calculateTotal(items) {
debugger; // 代码在此暂停
let total = 0;
for (const item of items) {
total += item.price * item.quantity;
debugger; // 每次循环暂停
}
return total;
}
// 在开发者工具中设置条件断点
// 右键行号 → Add conditional breakpoint
// 输入条件,如: i > 5
function processArray(arr) {
for (let i = 0; i < arr.length; i++) {
// 条件断点: i === 5
console.log(arr[i]);
}
}
// 1. 代码断点:在Sources面板点击行号
// 2. 条件断点:右键行号添加条件
// 3. DOM断点:Elements面板右键元素
// - subtree modifications: 子树修改
// - attribute modifications: 属性修改
// - node removal: 节点删除
// 4. XHR断点:Sources面板右侧XHR/fetch breakpoints
// 5. 事件监听断点:Sources面板右侧Event Listener Breakpoints
使用Sources面板进行调试。
// 调试按钮:
// F8 或 Ctrl+\\: 暂停/继续
// F10 或 Ctrl+': 单步跳过
// F11 或 Ctrl+;: 单步进入
// Shift+F11: 单步跳出
// Ctrl+.: 单步执行
// Scope面板:查看变量作用域
// Call Stack面板:查看调用堆栈
// Watch面板:监视表达式
// 在Watch面板添加表达式
// 可以监视变量、属性、计算结果
function processUser(user) {
const name = user.name;
const age = user.age;
const isValid = name && age >= 0;
// 监视:
// user.name
// user.age
// isValid
// name.length
return isValid;
}
// Call Stack面板显示函数调用链
function a() {
b();
}
function b() {
c();
}
function c() {
debugger; // 查看调用堆栈
// Call Stack:
// c
// b
// a
// (anonymous)
}
调试网络请求。
// Network面板功能:
// 1. 查看所有网络请求
// 2. 查看请求/响应头
// 3. 查看响应内容
// 4. 查看请求时间
// 5. 模拟网络速度
// 6. 禁用缓存
// 过滤请求
// XHR: Ajax请求
// JS: JavaScript文件
// CSS: 样式文件
// Img: 图片
// Doc: 文档
// 查看请求详情
fetch("/api/user")
.then(response => {
// 在Network面板查看:
// - Request URL
// - Request Method
// - Status Code
// - Request Headers
// - Response Headers
// - Response Body
return response.json();
});
分析和优化性能。
// 记录性能
// 1. 打开Performance面板
// 2. 点击Record
// 3. 执行操作
// 4. 停止记录
// 分析结果:
// - FPS: 帧率
// - CPU: CPU使用率
// - Network: 网络请求
// - Timings: 关键时间点
// - Main: 主线程活动
// performance API
console.log("页面加载时间:", performance.timing.loadEventEnd - performance.timing.navigationStart);
// 标记时间
performance.mark("start");
doSomething();
performance.mark("end");
// 测量
performance.measure("doSomething", "start", "end");
const measures = performance.getEntriesByName("doSomething");
console.log("耗时:", measures[0].duration);
// 清除标记
performance.clearMarks();
performance.clearMeasures();
// 检测长任务
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log("长任务:", entry.duration + "ms");
}
});
observer.observe({ entryTypes: ["longtask"] });
分析和修复内存问题。
// Memory面板功能:
// 1. Heap snapshot: 堆快照
// 2. Allocation instrumentation on timeline: 分配时间线
// 3. Allocation sampling: 分配采样
// 内存泄漏检测:
// 1. 创建基准快照
// 2. 执行操作
// 3. 创建新快照
// 4. 比较快照
// 常见内存泄漏
// 1. 全局变量
var globalVar = largeObject; // 泄漏
// 2. 闭包
function createClosure() {
const largeData = new Array(1000000);
return function() {
return largeData.length; // 持有largeData引用
};
}
// 3. 事件监听
element.addEventListener("click", handler);
// 忘记移除
// 4. 定时器
setInterval(() => {}, 1000);
// 忘记清除
// 解决方案
// 1. 使用局部变量
// 2. 及时清理引用
// 3. 移除事件监听
// 4. 清除定时器
调试移动设备上的网页。
// Android Chrome调试
// 1. 手机开启USB调试
// 2. 连接电脑
// 3. chrome://inspect
// iOS Safari调试
// 1. iPhone设置 → Safari → 高级 → Web检查器
// 2. Mac Safari → 开发 → [设备名]
// 模拟移动设备
// Chrome DevTools → Toggle device toolbar
// 或 Ctrl+Shift+M
// 设备模拟
// 1. 选择预设设备
// 2. 自定义分辨率
// 3. 模拟网络速度
// 4. 模拟触摸事件
// 媒体查询调试
// Elements面板右侧 → Media queries
实用的调试技巧。
// 1. 使用console.trace追踪调用
function problematicFunction() {
console.trace("调用追踪");
}
// 2. 使用console.table查看数据
const users = [
{ id: 1, name: "东巴文" },
{ id: 2, name: "db-w.cn" }
];
console.table(users);
// 3. 使用copy复制到剪贴板
copy(JSON.stringify(user));
// 4. 使用$0获取选中的元素
// 在Elements面板选中元素后
console.log($0);
// 5. 使用$_获取上一个结果
1 + 1;
console.log($_); // 2
// 使用async/await调试
async function fetchData() {
debugger;
const response = await fetch("/api/data");
debugger;
const data = await response.json();
debugger;
return data;
}
// 使用Promise链调试
fetch("/api/data")
.then(response => {
debugger;
return response.json();
})
.then(data => {
debugger;
console.log(data);
});
// 条件日志函数
function debugLog(condition, ...args) {
if (condition) {
console.log(...args);
}
}
const DEBUG = true;
debugLog(DEBUG, "调试信息");
debugLog(DEBUG, "用户数据:", user);
// 使用装饰器模式
function withDebug(fn, debug = false) {
return function(...args) {
if (debug) {
console.log(`调用 ${fn.name}`, args);
}
const result = fn.apply(this, args);
if (debug) {
console.log(`返回`, result);
}
return result;
};
}
掌握了调试技术后,让我们继续学习:
东巴文(db-w.cn) - 让编程学习更简单
🎯 东巴文寄语:调试是开发过程中必不可少的技能,熟练使用浏览器开发者工具、断点调试、性能分析等技巧可以大大提高问题定位效率。在 db-w.cn,我们帮你成为调试专家!