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中等同于
\x1Bc或process.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与浏览器略有差异,部分样式功能不支持
📚 参考资源
🔖 常用项目内配置参考
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