开发效率嗖嗖提升的 20 余个 console 方法

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开发效率嗖嗖提升的 20 余个 console 方法相关的知识,希望对你有一定的参考价值。

开发效率嗖嗖提升的 20 余个 console 方法

5 个基础输出函数

注*console.exception() 已经 deprecated,使用 console.error() 代替。

分别是: console.log()console.warn()console.error(), console.debug()console.info()。它们的用法都差不多,就放在这里集中说明了。

console.log() 应该是前端开发最常碰到的命令了,它会将传进去的参数转换成信息输出到 console 中,如:

const obj = 
  a: "1",
  b: 
    test: "test",
  ,
;

console.log("log", obj);

console.warn("warn", obj);

console.error("error", obj);

console.debug("debug", obj);

console.info("infor", obj);

五条函数的输出结果为:

其中 debug 因为属于是开发者看的信息,所以会被 console 所隐藏,想要展示可以通过修改 default levels 进行展开:

展开后为:

console.log() console.warn()console.error() 是 VSCode 中自带快捷键的 console 系列方法,直接使用 logwarnerror 可以快捷输出三个函数。

warnerror 代表警告和错误的意思,因此需要谨慎使用,而有些情况下 log 也的确有点用途,比如说:

因此开发中不妨也可以使用 debug 代替 log,这样在编译过程中也可以保留所需要的 log 信息。

高阶用法与小技巧

技巧 1,搭配解构使用

因为 v8 对解析 javascript 进行了预编译,有的时候就会导致执行结果的不一致,如:

const obj = 
  a: "1",
  b: 
    test: "test",
  ,
;

console.debug(obj);
obj.a = "2";

在输出的时候明明希望得到的结果是 a: 1,但是在展开后,因为 v8 引擎对代码执行进行了优化,得出来的结果确实 a: 2,这个时候就可以尝试搭配解构函数去进行输出,以得到预期结果:

console.debug( ...obj );
obj.a = "2";

字符格式化

其实现在也可以用 string literal 去解决,不过在 JavaScript 中也是可以使用比较传统的格式化方法,如:

console.debug("String: %s, Int: %d, Decimal: %f, Object: %o", "Hello", 1, 0.1, 
  string: "format",
);

渲染结果为:

这种语法对于学过 C/C++的应该来说非常熟悉。

使用 CSS

除了比较常见的用法之外,console 其实也可以添加 CSS,如:

console.debug(
  "Normal, %cRed, %cGreen",
  "color: red",
  "background-color: green; color: white"
);

这里 %c 代表使用 CSS。

dir

console.dir()console.dirxml() 两条指令。

大多数情况下 console.log()console.dir() 的区别不是很大,不过在获取 html 元素的时候就不一样了。对比输出 document.body 的结果:

log() 输出类似 HTML 树/结点 的结构,而 dir 会渲染类似于 JavaScript 对象的结构。如果想要更加直观的获取当前元素的属性(properties) 和 特性(attributes),如 value, innerHTML, onclick, key 等,可以使用 dir() 进行更方便的查询。

查询的方式可以通过 filter 或是 ctrl + f 二者协同合作,如我在 console 输出了几个元素,我想要查找 body 元素的 onclick 事件的绑定:

filter 会筛选出所有与 body 相关的输出,关键字查找则可以更方便的找出 onclick 所在的位置。注意,虽然 log() 输出和 dir() 输出的 body 都显示在了 console 上,但是只有 dir() 输出的 body 会显示 点击事件

console.dirxml() 的用处……我至今没找到。可能因为我主要用 chrome 开发,而且也不怎么操作 XML 吧。总之就觉得在 chrome 的开发环境下,dirxml()log() 的差异不大,而且因为 log 这个 VSCode 的快捷键,我更偏向于使用 log

table

console.table() 可以更直观的展开数据,依旧以上面的 object a 为例:

这是一个我日常开发中使用的比较少的输出命令,而且大部分情况我更倾向于用在数组,而非对象。个人感觉对象的展示效果不是很好,这个情况下比较难直观地了解对象的结构。

对于数组展示效果会更好一些,以下为二维数组的输出:

console.table([
  [1, 2, 3, 4, 5],
  [6, 7, 8],
  [1, 2, 3],
]);

显示结果为:

二维以上的数组应用场景太小了,这里就不具体讨论。

time

之前一般用得比较多的就是 Date,不过 time 其实也是一个比较好的解决方案。与时间相关的函数包含了:console.time(), console.timeLog(), 和 console.timeEnd,如:

const asyncCall = "async call";

console.time(asyncCall);

setTimeout(() => 
  console.timeEnd(asyncCall);
, 1000);

输出结果为:

与直接用 Date 相比,使用 console.time() 可以更简单地展示更加清晰的信息。

console.timeLog() 的用法是输出从开始到现在经过的时间,我修改了一下 JavaScript 循环中调用异步函数的三种方法,及为什么 forEach 无法工作的分析 的案例,将 Date 修改为了 console.time()

const asyncCall = "async call";

const map = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
  [4, "four"],
  [5, "five"],
]);

const timeout = () =>
  new Promise((resolve) => setTimeout(() => resolve([1, 2, 3, 4, 5])), 1000);

const getEl = (key) =>
  new Promise((resolve) => setTimeout(() => resolve(map.get(key)), 1000));

const getData = async () => 
  const data = await timeout();
  console.time(asyncCall);
  let str = [];
  for (let i = 0; i < data.length; i++) 
    const element = await getEl(data[i]);
    console.timeLog(asyncCall);
    str.push(element);
  

  console.timeEnd(asyncCall);
;

getData();

输出结果如下:

与使用 new Date() 相比,使用这种方法可以更方便地追踪代码出现的地方、次数以及频率的同时,减少声明局部变量的次数,如:

timeStamp

console.timeStamp() 有一些支持上的问题,目前看 MDN 说是 NodeJS 还无法支持。

这个方法会在 PerformanceWaterfall 留下标记,这个我还没有具体实验过,不过感觉会比较像这样的效果……吧。

group

group 系列的用法与 time 相似,同样具有 3 个方法:group(), groupCollapsed(), groupEnd(),不过 groupEnd() 不接受任何参数,会默认结束这层分组。案例代码如下:

const group = "group level 1";
const group2 = "group level 2";
const group3 = "group level 3";

console.log("outside any group");
console.group(group);
console.log("under" + group);
// console.group(group2);
console.groupCollapsed(group2);
console.log("under" + group2);
console.group(group3);
console.log("under" + group3);
console.groupEnd();
console.log("under" + group2);
console.groupEnd();
console.log("under" + group);
console.groupEnd();

展示效果如下:

其中,groupgroupCollapsed 都会创建一个新的分组,同时使用 groupgroupCollapsed 会创建两个分组。

profile

这个方法包括 console.profile();profileEnd();,使用效果如下:

const profile = "profile";

console.profile(profile);

setTimeout(() => 
  const x = "12345";
  let y;
  for (let i = 0; i < 10; i++) 
    y = i;
  
  console.profileEnd(profile);
, 1000);

这段代码其实要放到 Performance 中才能看到比较好的效果,例如说:

图 1 是使用了 profile 的情况,对比图 2 会有些许的差异。

profile 也有兼容性的问题,不推荐使用生产环境。

assert

如果用过 JUnit,Jest 之类的测试,对于 assert() 的用法应该很熟. assert() 在成功的情况下不会有任何的提示,但是一旦失败了就会在控制台上输出报错信息:

console.assert(1 == "1");
console.assert(1 === "1");
console.assert(1 === "4");

clear

清除整个 console 上的输出信息。

count

一个计数器,应用场景可以因地制宜。

我将前面提到的几个 console 方法结合了一下,做了这样的实现:

感觉一下就高大上起来了。

实现如下:

const asyncCall = "async call";

const map = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
  [4, "four"],
  [5, "five"],
]);

const timeout = () =>
  new Promise((resolve) => setTimeout(() => resolve([1, 2, 3, 4, 5])), 1000);

const getEl = (key) =>
  new Promise((resolve) => setTimeout(() => resolve(map.get(key)), 1000));

const getData = async () => 
  const data = await timeout();
  console.time(asyncCall);
  let str = [];
  for (let i = 0; i < data.length; i++) 
    const element = await getEl(data[i]);
    console.group(`getData for loop $i`);
    console.count(asyncCall);
    console.timeLog(asyncCall);
    console.groupEnd();
    str.push(element);
  

  console.timeEnd(asyncCall);
;

getData();

trace

这里使用了一下 MDN 的代码:

function foo() 
  function bar() 
    console.trace();
  
  bar();


foo();

效果如下:

为什么要知道这么多 console 函数

  1. 提升开发效率,尽管大多数情况下都说不推荐使用 console.XXX(),不过在不是很确定当前代码到底要做什么,或者只是想简单的看一下值是不是没有问题的情况下,使用 console.XXX() 会比使用 debugger 更加高效

  2. 秀同事一脸 ❌

  3. 可以写一个轻量的 package 给自己或项目使用,参考一下这个案例:

    function foo() 
      function bar() 
        console.trace();
      
      bar();
    
    
    const action = "action";
    const actionName = "@SOMETHING";
    const prevState = "prev state";
    
    console.group(
      `%c$action %c$actionName`,
      "color: #aaa",
      "font-weight: 700"
    );
    console.groupCollapsed(prevState);
    console.groupEnd();
    console.groupCollapsed(`%c$action`, "color: #448ee4; font-weight: 700");
    foo();
    console.groupEnd();
    console.groupEnd();
    

    这是模仿 redux-logger 的样式实现的非常简单的一个最外层复刻,样式如下:

    这就使用了几个组合技完成了一个简单的 logger 的实现。

以上是关于开发效率嗖嗖提升的 20 余个 console 方法的主要内容,如果未能解决你的问题,请参考以下文章

提升前端开发效率及查错能力的小技巧

IntelliJ IDEA这样配置,代码效率嗖嗖的

能够有效提升开发效率的 20 余款 VSCode 插件(多图带效果展示)

能够有效提升开发效率的 20 余款 VSCode 插件(多图带效果展示)

Goland嗖嗖的: 快捷键,自动生成代码等效率小技巧

Goland嗖嗖的: 快捷键,自动生成代码等效率小技巧