-->

谷歌浏览器不为人知的console调试方法!

2020-10-31 10:31发布


作者:anran758
https://anran758.github.io/

导读:作为一名Java程序员,chrome浏览器是最常打交道的软件之一,那么它的一些调试小技巧你了解多少呢?

目录

  • console

    • log
    • info, warn, error
    • table
    • group
    • dir
    • count
    • clear
    • time
    • assert
  • chrome devtools

    • $(selector, [startNode])
    • $$(selector, [startNode])
    • $
    • copy(obj)
    • inspect(object/function)
    • getEventListeners(obj)
    • monitor/unmonitor(function)
    • monitorEvents/unmonitorEvents(object[, events])
    • 别名

console

console 是浏览器提供的接口。它是一个对象,在控制台中可以查看当前浏览器支持哪一些方法。下面介绍一些比较实用的 api:


log

console.log 这可能是学习前端调试技术最基础的第一步了吧,你还记得最开始是从什么地方学习到使用这个方法来调试吗?

console.log(obj1 [, obj2, ..., objN);
console.log(msg [, subst1, ..., substN);

console.log 的功能就是向控制台输出一条信息。它可以传入多个参数,输出的行为取决于第一个参数是否是一个代替字符串。

如果是替换字符串,则后面的参数会依次替换掉字符串里的占位符; 如果不是替换字符串,则输出每一个参数的值:

var name = 'anran758';

// 常规使用方式,输出原始值
console.log('Hello'); // Hello
console.log(name); // anran758
console.log(`Hello, ${name}`); // Hello, anran758

// 第一个参数是替换字符串,后面是替换的规则
console.log('Hi, %s. what are you doing', name); // Hi, anran758. what are you doing
console.log('%c I am some great text''font-size: 50px;'); // 假装 50px: Hi, anran758. what are you doing

下面是替换字符串所支持的参数, 学习过 C 语言的同学是不是有种熟悉的感觉呀~

占位符 描述
%s 字符串
%d or %i 整数
%o or %O 对象
%f 浮点数
%c 样式代码

在使用时需要注意的一点是:不同占位符在传入值时会预先针对类型的不同而进行格式化,比如:

// 我们在使用了数字占位符,却传入字符串. 内部进行格式化时进行了类似 parseInt('anran758', 10) 的数据转换
// 因此替换结果为 NaN
console.log('result: %d''anran758'); // result: NaN

// 再比如,我们传入一个浮点数,经过数据格式化为 3。这一种是符合预期,因为我们要的就是整数
console.log('result: %d'3.25); // result: 3

了解了这些扩展方式后,我们可以来做一些有意思的事~

比如,如果你打开控制台去访问知乎、百度等网站时,可能会发现控制台有一些开发者留下的彩蛋~ 如招聘信息或者自家公司的立体 logo:

哔哩哔哩控制台输出

知乎控制台的输出

不过值得一提的是,js 规范中并没有规定 console 该如何实现,不同的浏览器调用 console 后的表现也会不一致。

这导致有一个常见的问题发生: 在调用接口时,明明请求的数据还没回来,打印出来却是有值的。实际上原因可能就是你所使用的浏览器,在实现时该 API 是异步的,它提前给你显示了出来。这个问题我在 segmentfault 的问答区中看到有很多朋友问了这样的问题,特意提一提这事。

解决的方法也很简单,如果你觉得这个值不对劲的话,你可以先将对象转为 json 字符串,然后再解析为对象, 这样就能将原始值输出。

console.log(JSON.parse(JSON.stringify(obj)));

info, warn, error

如果你使用过一些脚手架来搭建项目或者是使用过 SDK 的话,那么在控制台中你能看到以下相关的使用信息。

比如在载入程序时会发出一些运行信息会通过 log 或者 info 来输出信息。

或者你使用的框架中检测到你使用了一些将来可能会被废弃的 API,这时它可能会在控制抛出一个 warn 来警告你。

再或者你使用人家 SDK 的姿势不对,程序内部检测到压根不是这么用的,那么 SDK 内部会抛出错误信息,我们可以通过错误信息来进行排查错误。

这三个 API 更多的是给开发人员提供额外的信息,来查看页面的运行情况,更多用于被封装过后的组件或框架中。

// Info
console.info('Hi, This is message')

// warning 警告
console.warn('On, Your operation may cause a security breach!')

// Error 报错
console.error('Shit! Variable does not exist!')

table

console.table只接受一个数组或者对象, 可以接受一个额外的参数来描述表格的列数。它会把数据通过表格的形式打印出来, 这样我们看数据的时候就能直观了很多:

var array = [
  { name'Jack'age12 },
  { name'Tome'age18 },
  { name'baka'age15 }
];

console.table(array);

group

console.groupconsole.groupEnd 是成对出现的,就像我们使用的标签一样。group在控制台创建一个新的分组, 输出到控制台上的内容都会被添加一个缩进, 表示该内容属于当前分组, 直到调用 console.groupEnd() 之后, 当前分组才结束。

var boys = [
  { name'Jack'age12 },
  { name'Tome'age18 },
  { name'baka'age15 }
]

boys.forEach(item => {
  console.group(`${item.name}`)
  console.log(`This is ${item.name}`);
  console.log(`${item.name} is ${item.age} years old`);
  console.log(`${item.name} is ${item.age * 7} years old`);
  console.groupEnd(`${item.name}`)
})

dir

console.dir,在控制台中显示指定 JavaScript 对象的属性,并通过类似文件树样式的交互列表

我们知道console.log实际上是可以输出 DOM 节点的, 但很多时候我们想查看的不是 DOM 节点,而是该 DOM 节点下的属性,这里就可以使用 dir 来代替 log 来输出 DOM 节点对象.

var head = document.getElementById('head');

console.log(head);
console.dir(head);

但需要注意的是,这个功能是非标准的,尽量不要在生产模式下使用。


count

count, 如同字面意思一样. count()会输出每一次被调用的次数. 该方法的兼容性也需要注意, 不适用于生产模式.

console.count('anran758')
console.count('anran758')
console.count('zero')
console.count('anran758')
console.count('zero')
console.count('anran758')
console.count('zero')
console.count('anran758')

clear

clear可以清楚调用这个 API 之前的所有 log 信息,这在一个 log 很多很乱的情况下进行某个功能调试会很有作用。

// something info
console.clear();

time

启动一个计时器(timer)来跟踪某一个操作的占用时长。每一个计时器必须拥有唯一的名字。页面中最多能同时运行 10,000 个计时器。跟 group 一样, time 也是配套的。

当以此计时器名字为参数调用 console.timeEnd() 时,浏览器将以毫秒为单位,输出对应计时器所经过的时间.

比如我们统计一下请求接口的时间:

console.time('fetching data');
fetch('https://api.github.com/users/anran758')
  .then(data => data.json())
  .then(data => {
    console.timeEnd('fetching data');
    console.log(data);
  });

这样我们就轻易的知道了这次我们请求花费了多少时间啦~ 但值得注意的是,该方法的统计时间在微观下不够精准,更多时候我们还是需要使用更专业的测试工具后者网站来完成测试性能的工作。

assert

console.assert()还是蛮有意思的. 它第一个参数接受一个断言(声明), 第二个参数是一个message. 如果断言为 false,则将一个错误消息写入控制台。如果断言是 true,就当做没发生。语法如下:

console.assert(assertion, message [, subst1, ..., substN]);

这里的断言不一定是false才会触发错误. 我特意去测试了一下, 触发的规则也跟if的判断里的逻辑相反. 只要是断言是0, NaN, undefined, false, null, 空字符串('')这些假值就会激活报错.

// Assertion failed: Here is the "name" can not be empty
var str = '';
console.assert(str, 'Here is the "str" can not be empty');

// Assertion failed: 0 is not allowed!
var num = 0;
console.assert(0'0 is not allowed!');

// Assertion failed: That is wrong!
console.assert(1 === 2'That is wrong!');

// 什么都不会发生
console.assert(1 === 1'That is wrong!');


以上是 18.01.30 分享出来的内容,在这之后又发现了一些好用的功能,如果你跟笔者使用的都是 chrome 浏览器的话,可以继续往下看,笔者将逐一进行介绍:

chrome devtools

下面介绍 chrome devtools 在控制台提供的一些语法糖,这些方法只能控制台使用,而不能直接在代码里使用。区分是浏览器提供的还是我们自己代码中定义的方法可以使用console.log(method),如果打印出来的是 [Command Line API] 就是内置方法。

$(selector, [startNode])

我相信做过前端的朋友都了解 jqeury$ 选择器,乃至于我们看到这个符号就能联想到 DOM 相关的东西。

IE9+ 引入了 document.querySelector(),可以让我们很方便找到对应的 DOM 元素,但该 API 拼写起来确实有点麻烦,并且该方法的使用频率还不低。因此 chrome 开发工具提供一个$的别名给我们使用。

$ 接受两个参数,第一个参数接受一个选择器,第二个参数接受一个 DOM 元素表示从该元素下开始搜索,不传默认为 document.

我们可以简单做一个 demo 实验一下:

<!-- 一个简单的嵌套结构 -->
<div class="main main.container">
  <div class="start"></div>
  <div class="main content"></div>
  <div class="end"></div>
标签: