别再 console.log 走天下了!Console 家族全员出道,最后一个你肯定没用过

0 阅读5分钟

引言

“这个变量打印出来是啥?我看看……哦,是 [object Object]。”

“数组怎么展开这么麻烦?每次都要点一下。”

“我想知道这段代码执行了多久,难道要自己 Date.now() 减一下?”

如果你也有过这些灵魂拷问,那么恭喜你——你正在经历“前端菜鸟阶段”的标志性症状:console.log 依赖症

今天,我就带你认识 Console 家族的全明星阵容。它们不仅能让你告别 [object Object] 的尴尬,还能让你在调试时爽到飞起

一、console.log:老实人,但不够用

console.log 就像班级里的劳动委员,勤勤恳恳,但没啥特长。它能打印,但打印对象时只给你看个缩略图,数组长一点就折叠,想看清得手动点开。

更气人的是,你经常在代码里留下一堆 console.log,上线前删到手软。

是时候认识它的兄弟姐妹了。

二、console.table:把数据变成表格,一目了然

当你有一堆对象或者二维数组时,console.table 就是你的救星。

const users = [
  { name: '张三', age: 18, city: '北京' },
  { name: '李四', age: 22, city: '上海' },
  { name: '王五', age: 20, city: '广州' }
];
console.table(users);

控制台会直接输出一个可排序的表格!列名自动提取,比 log 一坨对象清晰一万倍。

你还可以指定要显示的列:console.table(users, ['name', 'city'])

适用场景:调试 API 返回的列表数据、查看对象数组。

三、console.time / console.timeEnd:自带秒表的计时器

想知道一段代码执行了多久?别再手动算 Date.now() 了。

console.time('fetchData');
await fetch('/api/data');
console.timeEnd('fetchData');
// 输出:fetchData: 234.5 ms

你可以同时开多个计时器,只要给不同的 label 就行。

适用场景:性能测试、优化前后对比、定位慢函数。

四、console.assert:条件断言,满足条件才打印

你想在某个条件为假时输出错误信息,但不想写 if 语句?

console.assert(user.age >= 18, '用户未成年!');
// 如果 age < 18,控制台会输出红色错误:Assertion failed: 用户未成年!

它不会中断代码执行,只是默默给你一个警告。

适用场景:参数校验、状态检查、快速调试假设条件。

五、console.group / console.groupEnd:给日志分个组,折叠大法好

当你的日志输出一大堆,分不清哪个是哪个时,分组功能让你笑出声。

console.group('用户登录流程');
console.log('1. 输入账号密码');
console.log('2. 点击登录按钮');
console.group('网络请求');
console.log('发送 POST /api/login');
console.log('收到响应 200');
console.groupEnd();
console.log('3. 跳转到首页');
console.groupEnd();

控制台里会生成可折叠的层级结构,再也不用在茫茫 log 海里找针了。

适用场景:复杂流程追踪、事件处理链路、递归函数调试。

六、console.count:自动计数器,不用自己声明变量

想知道某个函数被调用了多少次?或者某个循环执行了几轮?

function handleClick() {
  console.count('按钮点击次数');
  // ...
}
// 每次调用输出:按钮点击次数: 1、2、3...

console.count() 会记住每个 label 的调用次数。想重置?用 console.countReset('按钮点击次数')

适用场景:事件触发频率、递归深度检测、循环验证。

七、console.trace:打印调用栈,谁调用了我?

你发现一个函数被奇怪地调用了,但不知道从哪里来的?console.trace() 帮你打印当前调用路径。

function foo() {
  bar();
}
function bar() {
  console.trace('谁叫我?');
}
foo();
// 输出堆栈:bar -> foo -> (匿名)

适用场景:追踪意外调用、理解代码执行流、定位循环引用。

八、console.dir:以对象形式展示 DOM 元素

console.log(document.body) 输出的是一个 HTML 标签,展开后是 DOM 属性树。但有时你想看它的 JavaScript 对象结构(包括所有方法和属性),就用 console.dir

console.dir(document.body);

它会以可展开的对象树形式展示 DOM 元素,方便你查看原型链、事件监听器等。

适用场景:调试 DOM 元素、查看内置对象完整结构。

九、console.clear:清空控制台,还你一片净土

调试到一半,控制台已经刷了几百条 log,眼睛都花了。直接 console.clear(),干干净净。

十、冷门但有用:console.memory(非标准,Chrome 有)

在 Chrome 中,console.memory 可以查看当前页面的 JS 堆内存使用情况。虽然不是标准 API,但调试内存泄漏时很爽。

console.memory; // { jsHeapSizeLimit, totalJSHeapSize, usedJSHeapSize }

十一、实战:如何优雅地调试一个“神秘 bug”

假设你有一个按钮,点击后要加载数据,但有时候点了没反应。你怀疑是事件被多次绑定,或者请求超时。用 console 全家桶组合拳:

document.getElementById('btn').addEventListener('click', () => {
  console.groupCollapsed('按钮点击事件'); // 默认折叠的分组
  console.count('点击次数');
  console.time('请求耗时');
  
  fetch('/api/data')
    .then(res => res.json())
    .then(data => {
      console.table(data.slice(0, 5)); // 只显示前5条表格
      console.timeEnd('请求耗时');
    })
    .catch(err => {
      console.assert(err, '请求失败了!');
      console.trace('错误堆栈');
    });
  
  console.groupEnd();
});

一眼就能看出点击次数、请求耗时、返回数据,还能折叠分组不占空间。这才是专业调试!

十二、结尾彩蛋:上线前怎么一键删除所有 console?

你可以在 Webpack 或 Vite 中使用 terser 插件配置 drop_console: true,或者用 babel-plugin-transform-remove-console。但注意:console.errorconsole.warn 建议保留,方便线上排查问题。

十三、总结:console.log 只是冰山一角

Console API 有几十个方法,今天介绍的只是最常用的几个。下次调试时,别再只会 log 了。用 table 看数据,用 time 测性能,用 trace 找祖宗,用 group 整理现场——你会发现,调试也可以是一种享受。

每日一问:你还知道哪些神奇的 console 方法?或者你曾经因为 console.log 太多被同事吐槽过吗?评论区分享你的“日志惨案”!