长文揭秘 让人忽略的Console对象

Console 是我们日常开发调试使用场景最多的一种调试工具了,今天我们就来全面解析 Console 对象

成员方法

这些方法是 Console 对象的方法,用于在控制台输出不同类型的信息,以便于开发者进行调试和查看程序执行过程中的各种状态。下面简要介绍这些方法的用法:

console.error()

向 console error 控制台输出一条错误消息

console.info()

输出信息性消息,通常用于输出程序执行过程中的一般信息,比如指示性消息或操作成功的提示。

在 Firefox 和 Safari 浏览器中,Web 控制台的日志中的项目旁边会显示一个小的I图标, 在 Chrome 浏览器中 console.info 和 console.log 输出格式并无什么不同

在绝大多数场景下,console.info 和 console.log 功能非常相似,输出的效果基本上并无差异

  • Safari 浏览器中输出 console.info 和 console.log
  • Firefox 浏览器中输出 console.info 和 console.log
  • Chrome 浏览器中 console.info 和 console.log

console.log()

输出普通信息,通常用于调试和输出一般信息。展现效果基本上和 console.info 类似

console.warn()

console.warn() 是用于在控制台输出警告信息的方法. 通常用于指示潜在的问题或需要注意的情况。在控制台中,警告信息可能会以黄色或橙色 颜色或**⚠️图标**显示,以便用户能够更容易地识别出这是一条警告消息

console.dir()

是用于在控制台输出指定对象的属性列表的方法,在需要查看某些对象的属性的时候很有用,例如下面使用 console.dir 就可以很清楚地查看到这个正则表达式的各种属性

console.dirxml()

console.dirxml 方法用于在控制台中显示指定 XML 或 HTML 元素的内容,并以 XML 树的形式呈现。这对于查看和分析 DOM 结构非常有用。

console.dirxml 是非标准的,请尽量不要在生产环境中使用它!

console.table()

console.table() 是用于以表格形式在控制台中输出数组或对象的内容的方法。它接受一个数组或对象作为参数,并将其内容以表格的形式显示在控制台中,其中数组的每一项或对象的每一个属性将对应表格的一列。

console.trace()

console.trace() 是用于在控制台输出当前的调用栈的方法。

调用 console.trace() 会在控制台中显示当前 JavaScript 执行路径的函数调用栈信息,包括函数的调用顺序和调用位置。

这对于调试代码时追踪函数的调用路径和了解代码执行的流程非常有用。通过调用 console.trace(),开发人员可以快速了解代码的执行过程,并找到导致问题的函数调用路径。

console.trace() 接收零个或多个对象,与跟踪一起输出到控制台。这些对象的组装和格式与传递给 console.log() 方法时的格式相同。

console.group()

console.group() 方法用于创建一个新的分组,将相关的输出信息分组显示在控制台中。所有在 console.group() 和 console.groupEnd() 之间输出的内容都将被归类到同一个分组中,并以缩进的形式展示。

console.groupCollapsed()

console.groupCollapsed() 方法在 Web 控制台上创建一个新的分组。与 console.group() 方法的不同点是,新建的分组默认是折叠的。用户必须点击一个按钮才能将折叠的内容打开。

如果要结束当前 console.groupCollapsed 分组,则需要调用console.groupEnd 才可以

console.groupEnd()

和 console.group() 或者 console.groupCollapsed() 搭配使用,用来结束当前分组。

js 复制代码
  console.group("Test Group");
  console.log("1");
  console.info({ name: "info" });
  console.warn({ name: "warn" });
  console.error({ name: "error" });
  console.debug({ name: "debug" });
  console.groupEnd("这里传啥都可以,因为传啥都不会在控制台输出");
js 复制代码
  console.groupCollapsed("console.groupCollapsed");
  console.log("1");
  console.groupEnd();

console.clear()

console.clear() 用于清除开发者工具的控制台中的所有已输出的日志信息和其他内容。当调用 console.clear() 时,控制台将被清空,以便进行新的日志记录和调试。

当然你还可以直接 鼠标右键 清除当前控制台上的 日志信息 输出

console.count()

console.count() 用于计算和记录特定标识符被调用的次数,并将结果输出到开发者工具的控制台中。每次调用 console.count() 并提供相同的标识符时,计数器都会递增并显示在控制台中。

使用 console.count() 时,你可以提供一个可选的标识符作为参数,用于标识计数器。如果没有提供标识符,计数器将默认为一个空字符串。

js 复制代码
console.count(); // 输出:default: 1
console.count(); // 输出:default: 2
console.count('myCounter'); // 输出:myCounter: 1
console.count('myCounter'); // 输出:myCounter: 2
console.count(); // 输出:default: 3

案例demo

html 复制代码
 <button id="clickBtn">click</button>
<script>
  document.getElementById("clickBtn")
  .addEventListener("click", () => {
    console.count("click");
  });
</script>

console.countReset()

console.countReset() 用于重置指定标识符的计数器。这个方法允许你在开发者工具的控制台中重新开始某个特定标识符的计数。

html 复制代码
<button id="clickBtn">click</button>
<button id="resetClickBtn">reset click count</button>
<script>
  document.getElementById("clickBtn")
    .addEventListener("click", () => {
      console.count("click");
    });

  document.getElementById("resetClickBtn")
    .addEventListener("click", () => {
      console.countReset("click");
    });
</script>

console.assert()

console.assert() 用于在特定条件不满足时输出错误信息到开发者工具的控制台。它接受一个表达式作为第一个参数,如果该表达式的值为 false,则会将第二个参数作为错误信息输出到控制台中。

js 复制代码
console.assert(expression, message);
  • expression:要进行断言的表达式。
  • message:当表达式为 false 时要输出的错误信息。

如果 expression 的值为 true,则不会输出任何内容;

如果 expression 的值为 false,则会输出 message 到控制台。

js 复制代码
// 只有在 第一个参数 为 false 的时候
// 才会输出 ""1 === 2" 
console.assert(1 === 2, "1 === 2");

console.profile()

console.profile() 曾经用于启动浏览器性能分析器(Profiler Tab ),以捕获代码的运行时性能信息,从而帮助开发者分析和优化代码性能。

不过现在 Profiler Tab 已经在浏览器中被废弃了,取而代之的是 Performance 面板。

使用 console.profile() 结合 console.profileEnd() 会自动创建 Performance 面板的 快照,避免手动开启和关闭对网站某一时间段的性能监控

console.profile() 可以接受一个参数作为 命名描述信息 , 这样在调用多个 console.profile() 的时候可以进行区分,同时 console.profileEnd 也可以通过 命名描述信息 去关闭指定的 console.profile()

js 复制代码
const t = Date.now();
console.profile("测试profile" + t);
  setTimeout(() => {
    console.profileEnd("测试profile" + t);
  }, 3 * 1000);

console.profileEnd()

结束 CPU 性能分析。和 console.profile(tagName) 搭配使用。

在 console.profile() 之后立刻调用此 API 可能会导致其无法工作。为解决此问题,请在 setTimeOut 中至少延迟 5 毫秒后再调用。

  • 如果 console.profileEnd() 传了描述信息名字,并且它与正在记录的描述信息的名字相匹配,则此描述信息将会停止。
  • 如果 console.profileEnd() 传了描述信息名字,并且它与正在记录的描述信息的名字不匹配,则不会进行更改。
  • 如果 console.profileEnd() 没有传描述信息名字,最近启动记录的描述信息将会停止。

console.time()

用于测量代码执行所花费的时间。这个方法配合 console.timeEnd() 使用,能够非常方便地计算代码段的执行时间

js 复制代码
console.time("myTimer");
// 执行需要计时的代码,比如一个循环或者一段复杂的函数
let sum = 0;
for (let i = 0; i < 1000000; i++) {
  sum += i;
}
console.timeEnd("myTimer"); // 输出执行时间,单位为毫秒

使用 console.time() 和 console.timeEnd() 可以帮助你评估代码的性能,并找出可能需要优化的部分。

console.timeLog()

与 console.time() 结合使用,用于输出在代码执行过程中的时间戳信息。

js 复制代码
console.time("myTimer");
// 执行需要计时的代码,比如一个循环或者一段复杂的函数
let sum = 0;
for (let i = 0; i < 100; i++) {
  sum += i;
  console.timeLog("myTimer");
}
console.timeEnd("myTimer"); // 输出执行时间,单位为毫秒
console.timeStamp();

上面的截图显示出 console.timeLog 输出了循环中每一次循环时,距离 console.time("myTimer"); 执行时,所经过的时长

console.timeEnd()

停止计时,并输出从第一次执行 console.time(label); 到当前所经过的时间。

  • label 是一个字符串参数,用于标识计时器。它必须与之前调用 console.time() 中的 label 相同,以便将它们关联在一起。
js 复制代码
console.timeEnd(label);

console.timeStamp()

向浏览器的 Performance 或者 Waterfall 工具添加一个标记。这样可以让你将代码中的一个点和其他在时间轴上已记录的事件相关联,例如布局事件和绘制事件等。

你可以选择用一个参数来作为时间戳标签,然后标记旁边就会显示这个标签。

js 复制代码
console.timeStamp("测试timeStamp1");

console.context()

输出console 对象上下文, 目前看没发现有什么特殊的用途。

console.createTask()

这是一个新的 Api 用于将异步代码进行关联,使得我们在追踪代码调用堆栈的时候,更加清晰方便。不过这个 API目前只在高版本的浏览器(Chrome 106+)中才支持

ts 复制代码
interface Console {
  createTask(name: string): Task;
}

interface Task {
  run<T>(f: () => T): T;
}

console.createTask("测试createTask"); 调用之后,会返回将当前堆栈轨迹与创建的 task 对象相关联的 Task 实例。然后可以使用此 task 对象运行函数(以下示例中的 ``f)。task.run(f)` 会执行任何函数

未使用 console.createTask 时

js 复制代码
<!-- framework.js -->
function makeScheduler() {
  const tasks = [];

  return {
    schedule(f) {
      tasks.push({ f });
    },

    work() {
      while (tasks.length) {
        const { f } = tasks.shift();
        f();
      }
    },
  };
}

const scheduler = makeScheduler();

function loop() {
  scheduler.work();
  requestAnimationFrame(loop);
};

loop();
js 复制代码
<!-- example.js -->
function someTask() {
  console.trace("done!");
}

function businessLogic() {
  scheduler.schedule(someTask);
}

businessLogic();

通过 debug 或者 console.trace 函数调用可以看到 整个 函数的 Call Stack 调用栈

使用 console.createTask 效果如下,展示了更多的上下文的堆栈信息

js 复制代码
<!-- framework.js -->
function makeScheduler() {
  const tasks = [];

  return {
    schedule(f) {
      const task = console.createTask(f.name);
      tasks.push({ task, f });
    },

    work() {
      while (tasks.length) {
        const { task, f } = tasks.shift();
        task.run(f); // instead of f();
      }
    },
  };
}
js 复制代码
<!-- example.js -->
function someTask() {
  console.trace("done!");
}

function businessLogic() {
  scheduler.schedule(someTask);
}

businessLogic();

可以从输出的调用栈可以看出通过 console.createTask 调用之后可以输出更多的信息, 例如当前示例中的 schedule 和 businessLogic 函数等

成员属性

console.memory

输出 Javascript 使用的内存信息如下

各个属性含义依次为:

  • jsHeapSizeLimit: 上下文内可用堆的最大体积
  • totalJSHeapSize: 已分配的堆体积,以字节计算。
  • usedJSHeapSize: 当前 JS 堆活跃段(segment)的体积,以字节计算。

标识符

Console输出还支持 标识符 输出,支持的标识符有如下:

%s

  1. 用于字符串拼接,函数有 %s 的字符串参数将会用下一个参数进行替换
  2. 如果下一个参数中含有 %s 的话,就会使用空的字符串进行替换
  3. 如果存在多个%s的话,只会替换第一个出现的 %s
js 复制代码
// Hello, world!
console.log("Hello, %s!", "world"); 

// JsHello, world!
console.log("Js%s", "Hello, %s!", "world");

// Js2024 Hello, %s! world
console.log("Js%s", "2024", "Hello, %s!", "world"); 

%d 或 %i

用于整数替换,将指定的整数值插入到输出中。内部使用 parseInt(element, 10) 进行转换

js 复制代码
// 整数替换:%d 或 %i
console.log("Foo %d", 1.12); // Foo 1
console.log("Foo %i", 1.6); // Foo 1

%f

用于浮点数替换,将指定的浮点数插入到输出中。内部使用 parseFloat(element, 10) 进行转换

js 复制代码
//Foo 3.141592653589793
console.log("Foo %f", Math.PI);
// Foo NaN
console.log("Foo %f", Symbol(2.21));

%o 或 %O

用于对象替换,将指定的 JavaScript 对象插入到输出中。

js 复制代码
const detail = {
  name: {
    level: "master",
  },
};
console.log("Obj", detail);
console.log("Obj%o", detail);
console.log("Obj%O", detail);

%c

用于样式替换,指定样式应用于后续输出的文本。

这里支持以下css属性

  • background 与其全写版本。
  • border 与其全写版本。
  • border-radius
  • box-decoration-break
  • box-shadow
  • clear 和 float
  • color
  • cursor
  • display
  • font 与其全写版本。
  • line-height
  • margin
  • outline 与其全写版本。
  • padding
  • text-transform 这类 text-* 属性
  • white-space
  • word-spacing 和 word-break
  • writing-mode

基于上述支持的css属性,我们可以在console.log中,输出可以输出更多的可能。

番外:酷炫的控制台消息

上面我们说到的 %c 标识符支持 css 属性的表达,因此我们可以借助 css 的魔力在控制台上输出更多酷炫的信息。

%c 后面至少需要一个 字符 去占位承载样式的渲染,这里的示例是直接简单使用一个空格去占位,这样输出的空格也不会干扰我们的样式效果

图片

js 复制代码
 console.log(
        "%c ",
        'padding-left: 36px; line-height: 36px; background-image: url("data:image/gif;base64,R0lGODlhIAAgAPEBAAAAAP///wAAAAAAACH5BAEAAAIALAAAAAAgACAAAAKkhC+py3zfopxGvIsztsCGD4La2FVAGBoBuZnox45WcqLsum5KDWdvf1nwTo+fLbgDqo7LFCJJbOY0oidt6ozVKrtib0qaCnlYcJh7rf5iK6HZaM64VeS6L+pWf89WT+6vRAUBBVQ1gpOTJ4IYdxCnOBSJ8ZhkZNekk5ZSxpTpt6Y1eEVm00j3VALDmBXVyPEJB2r2ShoLh2ASqvU60dsr5yuBUQAAOw=="); background-size: 32px; background-repeat: no-repeat;  background-position: 2px 2px'
      );

只要你把图片转换成 base64 你可以显示任何图像数据

文本

js 复制代码
      console.log(
        "%cAdobe %cPhotoshop Web%c  %c2023.23.0.1%c  %c037a8af9746",
        "background: #666; border-radius:0.5em 0 0 0.5em; padding:0.2em 0em 0.1em 0.5em; color: white; font-weight: bold",
        "background: #666; border-radius:0 0.5em 0.5em 0; padding:0.2em 0.5em 0.1em 0em; color: white;",
        "",
        "background: #c3a650; border-radius:0.5em; padding:0.2em 0.5em 0.1em 0.5em; color: white;",
        "",
        "background: #15889f; border-radius:0.5em; padding:0.2em 0.5em 0.1em 0.5em; color: white;"
      );

svg动画

js 复制代码
console.info(
  '%c ',
  `line-height:200px;padding-block:100px;padding-left:200px;background-repeat:no-repeat;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cstyle%3E .wrapper %7B font-family: sans-serif; perspective: 500px; text-align: center; position: relative; width: 100%25; height: 100%25; %7D .cube %7B position: absolute; top: 20%25; left: 30%25; transform-style: preserve-3d; transform: rotateY(40deg) rotateX(-40deg); animation: wiggle_wiggle_wiggle_wiggle_wiggle_yeah 3s ease-in-out infinite alternate; %7D .side %7B width: 8rem; height: 8rem; background: rgba(0, 0, 0, 0.8); display: inline-block; position: absolute; line-height: 8rem; color: %23fff; text-align: center; box-sizing: border-box; border: 3px solid %23f00; font-size: 4rem; %7D .front %7B transform: translateZ(4rem); z-index: 1; %7D .back %7B transform: rotateY(180deg) translateZ(4rem); %7D .left %7B transform: rotateY(-90deg) translateZ(4rem); z-index: 1; %7D .right %7B transform: rotateY(90deg) translateZ(4rem); %7D .top %7B transform: rotateX(90deg) translateZ(4rem); %7D .bottom %7B transform: rotateX(-90deg) translateZ(4rem); %7D @keyframes wiggle_wiggle_wiggle_wiggle_wiggle_yeah %7B 0%25 %7B transform: rotateY(15deg) rotateX(-15deg); %7D 100%25 %7B transform: rotateY(60deg) rotateX(-45deg); %7D %7D %3C/style%3E%3CforeignObject width='100%25' height='100%25'%3E%3Cdiv xmlns='http://www.w3.org/1999/xhtml' class='wrapper'%3E%3Cdiv class='cube'%3E%3Cdiv class='side front'%3E1%3C/div%3E%3Cdiv class='side back'%3E6%3C/div%3E%3Cdiv class='side left'%3E3%3C/div%3E%3Cdiv class='side right'%3E4%3C/div%3E%3Cdiv class='side top'%3E2%3C/div%3E%3Cdiv class='side bottom'%3E5%3C/div%3E%3C/div%3E%3C/div%3E%3C/foreignObject%3E%3C/svg%3E")`
);

基本原理就是借助css的@keyframes和 animation实现的。所以一些简单的动画也是可以很好地在控制台是上展现

值得注意的是,如果涉及需要转移<、/>这些标签时,需要使用 encodeComponent 进行转义

值得一提的是,在console.info 中,展现的动画,并不会影响网站的性能,因为这些代码只会在控制台打开时运行,这对正常使用网站的用户而言是无感的,并不会影响用户的正常体验

链接文本

我们还可以直接在控制台输出可以点击的链接

js 复制代码
console.info("%chttps://baidu.com/",`line-height:88px;padding-block:44px;color:#ffb400;font-family:'Phosphate';font-size:36px;padding-inline:205px;`)

ASCII 字符

通过 ASCII 我们可以在控制台上输出各式各样的字符画,例如

js 复制代码
      const foo = `
         ┌─┐       ┌─┐
      ┌──┘ ┴───────┘ ┴──┐
      │                 │
      │       ───       │
      │  ─┬┘       └┬─  │     神兽保佑 永无bug
      │                 │
      │       ─┴─       │
      │                 │
      └───┐         ┌───┘
          │         │
          │         │
          │         │
          │         └──────────────┐
          │                        │
          │                        ├─┐
          │                        ┌─┘
          │                        │
          └─┐  ┐  ┌───────┬──┐  ┌──┘
            │ ─┤ ─┤       │ ─┤ ─┤
            └──┴──┘       └──┴──┘
                        `;
      console.log(
        `%c${foo}`,
        `font-family: monospace`
      );

emoji 表情

js 复制代码
console. info('%c✨Thanks for stopping byt', 'font-size:36px;')

以上控制台输出的效果,均在 Chrome 浏览器中运行,Firefox 和 Safari 浏览器可能会存在一些渲染差异以及支持的程度不同导致渲染的效果不一致。

以上就是Console对象的全面介绍,受限于笔者水平,如果错误,欢迎留言指正。

相关推荐
凤城老人1 小时前
从 PyQt6 到 Electron:给 Edge TTS 做一个“多角色配音机“的踩坑手记
javascript·typescript·electron
Dovis(誓平步青云)1 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan2 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_2 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
yivifu3 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
weixin_448290254 小时前
书庐开发实战教学
javascript·css·html
默_笙4 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript
一木 之林4 小时前
DeepSeek Agent 开发(一)
开发语言·前端·javascript
樱花落木兰6 小时前
分布式登录实战:Session 会话共享改造,Redis 存储用户登录状态
java·javascript·数据库·redis·分布式·缓存
liangshanbo12157 小时前
面试题:线上 JavaScript 报错如何快速定位到源码?
开发语言·javascript·ecmascript