Skip to content

JavaScript Console API 完全指南

💡 提示:所有示例代码均可直接在浏览器开发者工具的控制台中运行

📝 基础日志输出

1. console.log() - 通用日志

最常用的日志输出方法,适用于一般信息记录。

javascript
// 基础用法
console.log('Hello, world!')

// 输出对象(自动格式化)
console.log('用户信息:', { name: 'Alice', age: 26 })

// 输出多个参数
console.log('姓名:', 'Alice', '年龄:', 26, '角色:', 'admin')

// 输出时间戳
console.log('当前时间:', new Date().toLocaleString())

// 对象简写输出(ES6+)
const name = 'Alice', age = 26
console.log({ name, age }) // 等同于 { name: name, age: age }

实用场景

javascript
// API响应调试
fetch('/api/users')
  .then(res => res.json())
  .then(data => console.log('API返回:', data))

// 变量状态追踪
let count = 0
setInterval(() => console.log('计数器:', ++count), 1000)

2. console.info() - 信息提示

log() 功能相同,但在某些浏览器中带有信息图标(ℹ️)。

javascript
console.info('✅ 系统启动完成')
console.info('📦 当前版本:', '1.0.0')
console.info('🌐 API地址:', process.env.API_URL)

💡 浏览器差异:Chrome/Edge显示蓝色图标,Firefox显示信息图标,Safari与log()一致

3. console.warn() - 警告信息

输出带有黄色警告样式的消息,用于提示潜在问题。

javascript
// 性能警告
console.warn('⚠️ API响应时间过长:', '2.5s')

// 废弃提示
console.warn('⚠️ 即将废弃的功能:', 'oldMethod() 将在v2.0中移除')

// 兼容性警告
if (!navigator.geolocation) {
  console.warn('⚠️ 浏览器不支持地理定位API')
}

// 配置警告
if (config.timeout < 1000) {
  console.warn('⚠️ 超时时间过短,可能导致请求失败:', config.timeout)
}

4. console.error() - 错误信息

输出带有红色错误样式的消息,并包含完整的调用堆栈信息。

javascript
// 网络错误
console.error('❌ 网络请求失败:', '404 Not Found')

// 异常对象
try {
  JSON.parse('invalid json')
} catch (err) {
  console.error('❌ JSON解析错误:', err)
}

// 自定义错误
console.error('❌ 数据验证失败:', {
  field: 'email',
  value: 'invalid-email',
  message: '邮箱格式不正确'
})

// 错误追踪
function riskyOperation() {
  console.error('❌ 操作失败:', new Error('自定义错误信息'))
}

⏱️ 性能测量

5. console.time() & console.timeEnd() - 计时器

测量代码执行时间,用于性能分析和优化。

javascript
// 基础计时
console.time('数据加载')
fetchData().then(() => {
  console.timeEnd('数据加载') // 输出: 数据加载: 125.43ms
})

// 多个计时器同时运行
console.time('总耗时')
console.time('数据库查询')
await db.query('SELECT * FROM users')
console.timeEnd('数据库查询')

console.time('数据处理')
processData(data)
console.timeEnd('数据处理')
console.timeEnd('总耗时')

// 嵌套计时
console.time('完整流程')
  console.time('步骤1')
  step1()
  console.timeEnd('步骤1')
  
  console.time('步骤2')
  step2()
  console.timeEnd('步骤2')
console.timeEnd('完整流程')

性能分析实例

javascript
// 比较不同实现的性能
function comparePerformance() {
  const arr = Array.from({ length: 100000 }, (_, i) => i)
  
  // 方案1: for循环
  console.time('for循环')
  let sum1 = 0
  for (let i = 0; i < arr.length; i++) {
    sum1 += arr[i]
  }
  console.timeEnd('for循环')
  
  // 方案2: forEach
  console.time('forEach')
  let sum2 = 0
  arr.forEach(n => sum2 += n)
  console.timeEnd('forEach')
  
  // 方案3: reduce
  console.time('reduce')
  const sum3 = arr.reduce((acc, n) => acc + n, 0)
  console.timeEnd('reduce')
}

6. console.timeLog() - 中间计时

在不结束计时器的情况下输出当前经过的时间(Chrome 71+)。

javascript
console.time('长任务')
await step1()
console.timeLog('长任务', '步骤1完成') // 输出当前耗时但继续计时

await step2()
console.timeLog('长任务', '步骤2完成')

await step3()
console.timeEnd('长任务') // 输出总耗时并结束计时

7. console.count() - 计数器

统计代码执行次数,自动累加计数。

javascript
// 基础计数
function clickHandler() {
  console.count('按钮点击') // 第1次: 按钮点击: 1
  // 执行业务逻辑
}

// 分类统计
const events = ['click', 'scroll', 'click', 'resize', 'click']
events.forEach(event => {
  console.count(`事件: ${event}`)
})
// 输出:
// 事件: click: 1
// 事件: scroll: 1
// 事件: click: 2
// 事件: resize: 1
// 事件: click: 3

// 重置计数器
console.count('请求') // 请求: 1
console.count('请求') // 请求: 2
console.countReset('请求')
console.count('请求') // 请求: 1(重新开始)

// 默认计数器(不传参数)
console.count() // default: 1
console.count() // default: 2

实际应用

javascript
// 监控API调用频率
function apiCall(endpoint) {
  console.count(`API调用: ${endpoint}`)
  // 当计数过高时发出警告
}

// 追踪函数执行次数
function expensiveOperation() {
  console.count('耗时操作执行次数')
  // ... 业务逻辑
}

📊 数据可视化

8. console.table() - 表格显示

以表格形式展示数组或对象数据,极大提高可读性。

javascript
// 展示对象数组
const users = [
  { id: 1, name: 'Alice', age: 26, role: 'admin', active: true },
  { id: 2, name: 'Bob', age: 27, role: 'user', active: true },
  { id: 3, name: 'Carl', age: 30, role: 'user', active: false }
]
console.table(users)

// 只显示特定列
console.table(users, ['name', 'age'])

// 展示简单对象
const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
  retries: 3,
  debug: true
}
console.table(config)

// 展示二维数组
const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]
console.table(matrix)

// 展示Map和Set(Chrome/Edge)
const userMap = new Map([
  ['user1', { name: 'Alice', score: 95 }],
  ['user2', { name: 'Bob', score: 87 }]
])
console.table(userMap)

数据分析实例

javascript
// API响应数据分析
fetch('/api/products')
  .then(res => res.json())
  .then(products => {
    // 快速查看产品列表
    console.table(products, ['id', 'name', 'price', 'stock'])
    
    // 按价格排序后查看
    const sorted = products.sort((a, b) => b.price - a.price)
    console.table(sorted.slice(0, 10), ['name', 'price'])
  })

9. console.dir() - 对象结构

以可交互的树形结构显示对象的所有属性(包括原型链)。

javascript
// 查看DOM元素的完整属性
const btn = document.querySelector('button')
console.dir(btn) // 显示所有属性和方法

// 对比log和dir的区别
console.log(document.body) // 显示HTML结构
console.dir(document.body) // 显示对象属性

// 查看函数对象
function MyClass() {}
MyClass.prototype.method = function() {}
console.dir(MyClass) // 查看函数的属性和原型

10. console.dirxml() - XML/HTML 结构

以树形结构显示XML或HTML元素(等同于在Elements面板中查看)。

javascript
const container = document.querySelector('#app')
console.dirxml(container) // 显示完整的DOM树

🗂️ 日志分组

11. console.group() - 日志分组

将相关日志组织在一起,支持嵌套和展开/折叠。

javascript
// 展开式分组(默认展开)
console.group('📋 用户认证流程')
console.log('✓ 验证用户名密码')
console.log('✓ 生成访问令牌')
console.log('✓ 返回用户信息')
console.groupEnd()

// 折叠式分组(默认折叠)
console.groupCollapsed('🔍 调试信息')
console.info('请求URL:', '/api/login')
console.info('请求方法:', 'POST')
console.info('请求头:', { 'Content-Type': 'application/json' })
console.info('请求体:', { username: 'alice', password: '***' })
console.groupEnd()

// 多层嵌套分组
console.group('🌐 HTTP请求')
  console.log('发送请求...')
  
  console.group('📤 请求信息')
    console.log('URL:', 'https://api.example.com/users')
    console.log('Method:', 'GET')
    console.log('Headers:', { Authorization: 'Bearer token' })
  console.groupEnd()
  
  console.group('📥 响应信息')
    console.log('Status:', 200)
    console.log('Data:', { users: [...] })
  console.groupEnd()
console.groupEnd()

实际应用

javascript
// API请求日志封装
function logAPICall(method, url, data, response) {
  console.groupCollapsed(`🌐 ${method} ${url}`)
  console.log('⏰ 时间:', new Date().toLocaleString())
  if (data) console.log('📤 请求数据:', data)
  console.log('📥 响应数据:', response)
  console.log('✓ 状态:', response.status)
  console.groupEnd()
}

// 复杂业务流程追踪
async function processOrder(order) {
  console.group(`📦 订单处理 #${order.id}`)
  
  console.log('1️⃣ 验证订单信息')
  validateOrder(order)
  
  console.log('2️⃣ 检查库存')
  await checkInventory(order.items)
  
  console.log('3️⃣ 计算总价')
  const total = calculateTotal(order)
  
  console.log('4️⃣ 创建支付订单')
  await createPayment(total)
  
  console.groupEnd()
}

🔍 调试工具

12. console.trace() - 调用堆栈

输出当前代码的完整调用路径,帮助追踪函数执行流程。

javascript
function levelThree() {
  console.trace('🔍 追踪调用路径')
}

function levelTwo() {
  levelThree()
}

function levelOne() {
  levelTwo()
}

levelOne()
// 输出完整的调用栈:
// levelThree @ script.js:2
// levelTwo @ script.js:6
// levelOne @ script.js:10
// (anonymous) @ script.js:13

调试实例

javascript
// 追踪事件触发源
document.addEventListener('click', function handler(e) {
  console.trace('点击事件触发路径')
})

// 调试递归函数
function fibonacci(n) {
  if (n <= 1) {
    console.trace(`递归结束: n=${n}`)
    return n
  }
  return fibonacci(n - 1) + fibonacci(n - 2)
}

13. console.assert() - 条件断言

仅在条件为 false 时输出错误信息,适合调试和验证假设。

javascript
// 基础断言
const num = 5
console.assert(num > 10, '❌ 数值不符合预期:', num)

// 复杂条件断言
const user = { name: 'Alice', age: 16 }
console.assert(
  user.age >= 18, 
  '❌ 用户年龄不符合要求:', 
  `${user.name}只有${user.age}岁,需满18岁`
)

// 数组验证
const scores = [85, 92, 45, 78, 95]
scores.forEach((score, index) => {
  console.assert(
    score >= 60, 
    `❌ 第${index + 1}个成绩不及格:`, 
    score
  )
})

// 类型检查
function calculateArea(width, height) {
  console.assert(
    typeof width === 'number' && typeof height === 'number',
    '❌ 参数类型错误:',
    { width, height }
  )
  return width * height
}

// API响应验证
fetch('/api/users')
  .then(res => res.json())
  .then(data => {
    console.assert(Array.isArray(data), '❌ 响应数据应为数组')
    console.assert(data.length > 0, '❌ 用户列表为空')
    console.assert(data[0].hasOwnProperty('id'), '❌ 缺少id字段')
  })

单元测试风格断言

javascript
function test(description, fn) {
  console.group(`🧪 测试: ${description}`)
  try {
    fn()
    console.log('✅ 通过')
  } catch (err) {
    console.error('❌ 失败:', err.message)
  }
  console.groupEnd()
}

test('数组求和函数', () => {
  const result = sum([1, 2, 3])
  console.assert(result === 6, `期望6,实际${result}`)
})

🎨 样式化输出

14. console.log() 样式化

使用 CSS 样式美化控制台输出,让重要信息更醒目。

javascript
// 基础样式(使用 %c 占位符)
console.log(
  '%c ✓ 成功',
  'background: #2ed573; color: white; padding: 4px 8px; border-radius: 3px; font-weight: bold;'
)

// 多段样式组合
console.log(
  '%c 成功 %c 警告 %c 错误',
  'background: #2ed573; color: white; padding: 2px 5px; margin: 0 2px;',
  'background: #ffa502; color: white; padding: 2px 5px; margin: 0 2px;',
  'background: #ff4757; color: white; padding: 2px 5px; margin: 0 2px;'
)

// 渐变背景
console.log(
  '%c 🚀 应用启动成功',
  `
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  font-size: 20px;
  font-weight: bold;
  padding: 15px 30px;
  border-radius: 8px;
  text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
  border: 2px solid #764ba2;
  `
)

// 文本样式
console.log(
  '%c 大标题 %c 小说明',
  'font-size: 24px; font-weight: bold; color: #333;',
  'font-size: 12px; color: #666; font-style: italic;'
)

// 图标 + 文字
console.log(
  '%c ⚡ %c 性能优化建议',
  'font-size: 30px;',
  'font-size: 16px; color: #ff6348; font-weight: bold;'
)

实用样式预设

javascript
// 创建样式工具
const styles = {
  success: 'background: #2ed573; color: white; padding: 4px 8px; border-radius: 3px;',
  error: 'background: #ff4757; color: white; padding: 4px 8px; border-radius: 3px;',
  warning: 'background: #ffa502; color: white; padding: 4px 8px; border-radius: 3px;',
  info: 'background: #1e90ff; color: white; padding: 4px 8px; border-radius: 3px;',
  title: 'font-size: 20px; font-weight: bold; color: #2c3e50;',
  subtitle: 'font-size: 14px; color: #7f8c8d; font-style: italic;'
}

// 使用预设样式
console.log('%c ✓ 数据保存成功', styles.success)
console.log('%c ⚠ 连接超时', styles.warning)
console.log('%c ✗ 加载失败', styles.error)

// 封装日志工具
const logger = {
  success: (msg) => console.log(`%c ✓ ${msg}`, styles.success),
  error: (msg) => console.log(`%c ✗ ${msg}`, styles.error),
  warning: (msg) => console.log(`%c ⚠ ${msg}`, styles.warning),
  info: (msg) => console.log(`%c ℹ ${msg}`, styles.info)
}

logger.success('操作完成')
logger.error('操作失败')

创意应用

javascript
// ASCII艺术
console.log('%c',
  `font-family: monospace; font-size: 12px; color: #2ed573;
  `,
  `
   _____ _                 _      
  / ____| |               | |     
 | |    | | __ _ _   _  __| | ___ 
 | |    | |/ _\` | | | |/ _\` |/ _ \\
 | |____| | (_| | |_| | (_| |  __/
  \\_____|_|\\__,_|\\__,_|\\__,_|\\___|
  `
)

// 表格样式日志
console.log(
  '%c 用户 %c Alice %c 登录成功',
  'background: #34495e; color: white; padding: 2px 5px;',
  'background: #3498db; color: white; padding: 2px 5px;',
  'background: #2ecc71; color: white; padding: 2px 5px;'
)

🧹 控制台管理

15. console.clear() - 清空控制台

清除控制台中的所有日志信息。

javascript
console.log('这条消息将被清除')
console.log('这条也会被清除')

// 延迟清空
setTimeout(() => {
  console.clear()
  console.log('✨ 控制台已清空')
}, 2000)

// 条件清空
if (process.env.NODE_ENV === 'production') {
  console.clear() // 生产环境清空所有调试信息
}

注意

  • console.clear() 在某些环境下可能被禁用(如浏览器设置或开发工具选项)
  • 在Node.js中等同于 \x1Bcprocess.stdout.write('\x1Bc')

🔧 浏览器专属功能

Chrome DevTools 独有

javascript
// 1. $0 - $4: 最近选中的元素
// 在Elements面板选中元素后,可以在Console中使用
$0 // 最近选中的元素
$1 // 倒数第二个选中的元素

// 2. $() 和 $$(): 快捷选择器
$('#app') // 等同于 document.querySelector('#app')
$$('.item') // 等同于 document.querySelectorAll('.item')

// 3. $x(): XPath选择器
$x('//button') // 选择所有button元素

// 4. copy(): 复制到剪贴板
copy($0) // 复制选中元素的HTML
copy({ name: 'Alice', age: 26 }) // 复制对象的JSON字符串

// 5. keys() 和 values()
keys({ a: 1, b: 2 }) // ['a', 'b']
values({ a: 1, b: 2 }) // [1, 2]

// 6. monitor() 和 unmonitor(): 监控函数调用
function myFunction(a, b) {
  return a + b
}
monitor(myFunction)
myFunction(1, 2) // 会在控制台输出: function myFunction called with arguments: 1, 2
unmonitor(myFunction)

// 7. monitorEvents() 和 unmonitorEvents(): 监控DOM事件
monitorEvents(window, 'resize')
monitorEvents($0, ['click', 'mouseover'])
unmonitorEvents(window)

// 8. getEventListeners(): 查看元素的事件监听器
getEventListeners($0)

// 9. queryObjects(): 查找构造函数的所有实例
class User {}
const user1 = new User()
const user2 = new User()
queryObjects(User) // 返回所有User实例

Firefox DevTools 独有

javascript
// 1. :screenshot: 截取控制台内容
// 在命令中输入 :screenshot 或 :screenshot --fullpage

// 2. :block 和 :unblock: 阻止网络请求
// :block https://example.com/api

// 3. 多行编辑器
// Ctrl+B (Cmd+B) 切换到多行编辑模式

📊 性能分析实战

1. 内存泄漏检测

javascript
// 检测内存增长
let baseline = performance.memory.usedJSHeapSize

setInterval(() => {
  const current = performance.memory.usedJSHeapSize
  const growth = current - baseline
  console.log('内存增长:', (growth / 1024 / 1024).toFixed(2), 'MB')
  baseline = current
}, 5000)

2. 长任务监控

javascript
// 监控超过50ms的长任务
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.warn('检测到长任务:', {
      name: entry.name,
      duration: `${entry.duration.toFixed(2)}ms`,
      startTime: entry.startTime
    })
  }
})

observer.observe({ entryTypes: ['longtask'] })

3. 渲染性能分析

javascript
// 监控帧率
let lastTime = performance.now()
let frames = 0

function measureFPS() {
  frames++
  const currentTime = performance.now()
  
  if (currentTime >= lastTime + 1000) {
    const fps = Math.round((frames * 1000) / (currentTime - lastTime))
    console.log(`FPS: ${fps}`)
    frames = 0
    lastTime = currentTime
  }
  
  requestAnimationFrame(measureFPS)
}

measureFPS()

🎯 调试最佳实践

1. 日志级别规范

级别使用场景示例
debug详细的调试信息变量值、函数调用
info一般信息系统状态、流程节点
warn警告信息性能问题、废弃提示
error错误信息异常、失败操作

2. 命名约定

javascript
// ✅ 使用描述性标签
console.time('用户数据加载')
console.count('API请求: /users')

// ❌ 避免模糊标签
console.time('timer1')
console.count('count')

3. 避免过度日志

javascript
// ❌ 不要在循环中大量输出
for (let i = 0; i < 10000; i++) {
  console.log(i) // 会严重影响性能
}

// ✅ 使用采样或汇总
let sum = 0
for (let i = 0; i < 10000; i++) {
  sum += i
}
console.log('循环结果:', sum)

4. 清理生产代码

javascript
// 使用工具自动移除console(如Terser、babel-plugin-transform-remove-console)

// 或使用条件编译
const logger = {
  log: process.env.NODE_ENV === 'development' ? console.log : () => {},
  error: console.error // 错误日志保留
}

ℹ️ 注意:Node.js环境的Console API与浏览器略有差异,部分样式功能不支持

📚 参考资源

🔖 常用项目内配置参考

logger.ts
typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-console */
const { VITE_LOG_ENABLE } = import.meta.env

const logWithTimestamp = (message?: any, ...optionalParams: any[]) => {
  if (VITE_LOG_ENABLE === 'true') {
    const timestamp = new Date().toLocaleString()
    console.log(`[${timestamp}]`, message, ...optionalParams)
  }
}

const infoWithTimestamp = (message?: any, ...optionalParams: any[]) => {
  const timestamp = new Date().toLocaleString()
  console.info(`[${timestamp}]`, message, ...optionalParams)
}

const warnWithTimestamp = (message?: any, ...optionalParams: any[]) => {
  const timestamp = new Date().toLocaleString()
  console.warn(`[${timestamp}]`, message, ...optionalParams)
}

const errorWithTimestamp = (message?: any, ...optionalParams: any[]) => {
  const timestamp = new Date().toLocaleString()
  console.error(`[${timestamp}]`, message, ...optionalParams)
}

const debugWithTimestamp = (message?: any, ...optionalParams: any[]) => {
  const timestamp = new Date().toLocaleString()
  console.debug(`[${timestamp}]`, message, ...optionalParams)
}

const logger = {
  log: logWithTimestamp,
  info: infoWithTimestamp,
  warn: warnWithTimestamp,
  error: errorWithTimestamp,
  debug: debugWithTimestamp
}

export default logger