第三章:Console 面板精通:console.log 的进阶用法
说实话,很多人用 console.log 就只会扔一个变量进去。
我见过不少同事,调试时满屏都是 undefined 和 [object Object]。嗯,这其实挺浪费 Console 面板的潜力的。今天我就带你看看,console.log 到底能玩出什么花来。
3.1 占位符:让输出更清晰
console.log 支持类似 C 语言的 printf 风格占位符。我个人习惯用这个来格式化输出,比拼接字符串清爽多了。
const user = { name: '张三', age: 28 };
console.log('用户信息:%s,年龄:%d', user.name, user.age);
// 输出:用户信息:张三,年龄:28
// 更实用的场景:调试对象
const data = { id: 1, title: '调试技巧' };
console.log('数据对象:%o', data); // %o 会展开对象
我在项目中遇到过一个问题:后端返回的嵌套对象,用 console.log 直接打印根本看不清层级。后来用 %o 配合 JSON.stringify,一眼就找到了数据缺失的字段。
3.2 分组:让日志不再杂乱
当你的日志输出量很大时,分组功能简直是救星。
console.group('用户登录流程');
console.log('开始验证用户名');
console.log('验证密码');
console.group('权限检查');
console.log('检查角色');
console.log('检查资源权限');
console.groupEnd();
console.log('登录完成');
console.groupEnd();
你想想看,如果不用分组,这些日志会混在一起。一旦流程复杂,你根本分不清哪条日志属于哪个阶段。
3.3 表格:数组和对象的可视化
console.table 是我最常用的调试工具之一。为什么?因为人类天生对表格敏感。
const users = [
{ name: '李四', age: 25, role: 'admin' },
{ name: '王五', age: 30, role: 'user' },
{ name: '赵六', age: 22, role: 'editor' }
];
console.table(users);
这段代码会在 Console 面板里生成一个漂亮的表格。你可以点击列头排序,还能直接复制数据。我曾经用它来对比两个 API 返回的数据差异,比肉眼一行行看快多了。
还有个隐藏用法:你可以指定只显示某些列。
console.table(users, ['name', 'role']); // 只显示 name 和 role 两列
3.4 计时:性能分析的入门工具
想知道某段代码跑了多久?别用 Date.now() 手动减了,console.time 和 console.timeEnd 就是干这个的。
console.time('数据加载');
// 模拟异步请求
setTimeout(() => {
console.timeEnd('数据加载'); // 输出:数据加载: 1000.123ms
}, 1000);
更进阶的用法:console.timeLog 可以在计时过程中输出中间结果。
console.time('循环处理');
for (let i = 0; i < 1000000; i++) {
if (i === 500000) {
console.timeLog('循环处理', '已处理一半');
}
}
console.timeEnd('循环处理');
嗯,这个在优化长列表渲染时特别有用。你可以精确知道哪个阶段最耗时。
console.warn、console.error、console.assert 的使用场景
这三个方法,说白了就是给日志打标签。但很多人用错了地方。
3.5 console.warn:黄色警告,别忽视
console.warn 输出黄色背景的警告信息。它不会中断代码执行,但会在 Console 面板里显示一个警告图标。
function parseConfig(config) {
if (!config.version) {
console.warn('配置缺少 version 字段,将使用默认版本');
config.version = '1.0.0';
}
// 继续处理...
}
我建议在以下场景使用 warn:
- API 返回了非关键性错误,但需要提醒开发者
- 某个功能即将废弃,提示迁移
- 用户输入了不推荐的值,但程序还能继续运行
3.6 console.error:红色警报,必须处理
console.error 输出红色背景的错误信息。它同样不会中断代码,但会附带堆栈信息。
try {
const data = JSON.parse(response);
} catch (e) {
console.error('JSON 解析失败,原始数据:', response, '错误:', e);
// 这里可以继续执行降级逻辑
}
我曾经犯过一个错误:在 catch 里只用了 console.log。结果线上出了问题,日志里全是普通信息,根本分不清哪些是真正的错误。后来我强制团队规定:所有 catch 块必须用 console.error。
3.7 console.assert:条件断言的利器
console.assert 接受一个条件和一个消息。条件为 false 时,输出错误信息。
function calculateDiscount(price, rate) {
console.assert(price > 0, '价格必须大于0,当前值:', price);
console.assert(rate >= 0 && rate <= 1, '折扣率必须在0-1之间');
return price * rate;
}
你想想看,这比写 if 判断然后 console.error 简洁多了。一行代码搞定断言和日志。
但要注意:console.assert 不会抛出异常。它只是打印错误。所以它适合用在「非致命但需要关注」的校验场景。
我记得有一次调试一个复杂的表单验证逻辑,用了十几个 console.assert 来校验每个字段的中间状态。配合分组功能,一眼就看出是哪个校验条件没通过。
3.8 综合实战:一个完整的调试示例
最后,我给你看一个我在项目中实际用过的调试代码片段。
function fetchUserData(userId) {
console.assert(userId > 0, '无效的用户ID');
console.time('获取用户数据');
console.groupCollapsed('用户数据请求');
console.log('请求参数:%o', { userId });
return fetch(`/api/user/${userId}`)
.then(res => {
if (!res.ok) {
console.warn('请求状态异常:', res.status);
}
return res.json();
})
.then(data => {
console.table([data], ['id', 'name', 'email']);
console.timeEnd('获取用户数据');
console.groupEnd();
return data;
})
.catch(err => {
console.error('获取用户数据失败:', err);
console.groupEnd();
});
}
这段代码里,我用了 assert 做前置校验,time/timeEnd 做性能监控,group 做日志分组,table 做数据展示,warn 和 error 做分级提示。一个函数就把 Console 面板的潜力发挥到了极致。
嗯,下次调试的时候,试试这些方法。你会发现 Console 面板远比你想象的强大。