devTools之Console面板

1,929 阅读3分钟

控制台有两个主要用途: 查看日志和运行JavaScript

查看日志

平时在开发过程中,我们总是借助console来辅助调试,那么console是个什么东西呢?我们可以在Console面板打印下看看。 console对象.png 可以看到console对象上有很多方法,总的来说可以分为两大类,日志和非日志。

日志

DevToolsconsole中的打印日志的方法定义了四个级别,分别是VerboseInfoWarningError。如下表格所示:

级别方法
Verbosedebug
Infolog、info、count、countReset、dir、dirxml、table、time、timeEnd、trace
Warningwarn
Errorerror、assert

在控制台我们也可以通过日志级别来过滤日志,如下图所示: 日志级别.png

下面来看下这些方法的使用:

Info

①、loginfo

日常开发中使用最多的就是log了,info与它等价。如果有需要的话,也可以设置输出日志的样式,比如console.log('%c hello word', 'color: red; font-size: 30px')。如下图所示: log.png 如果想要输出的日志带上时间,可以shift+ctrl+ p调出命令行,在上面的输入框中输入show time,然后选中show timestamps即可。 image.png

log输出对象的时候需要注意一个小细节,参考如下demo: 都踩过的坑.png

obj的值是在第五行修改的,但是在第四行的时候打印出的obj的值,已经是修改后的值了,这是因为当我们手动展开该变量的时候,控制台才获取该变量的值。如果想要在第四行准确输出obj的值,可以使用console.log(JSON.stringify(obj))输出。

②、countcountReset

countcountReset是配套使用的,用于计数和重置计数。举个例子,在下面的demo中定义了一个add方法,然后add在不同的情况下被调用,那么可以用count来计算add一共调用了多少次。

function add(a, b) {
    console.count('call add') // count的入参可以是自定的标签名,缺省是default
    return a + b
}
add(1,2)
add(1,3)
console.countReset('call add')
add(1,4)

demo的运行结果如下:

call add: 1
call add: 2
call add: 1 # 因为countReset将计数器重置了,所以又从1开始了

③、dirdirxml dir用于打印一个对象的属性和方法,而dirxml则用于打印DOM节点。如下图所示: image.png

psdirdirxml都是非标准特性。

④、table

table用于打印一个数组中的数据,如下图所示: table.png 如果只需要显示一列或者某几列,可以使用第二个可选参数来指定需要展示的列,如下图所示: table第二个参数.png

⑤、timetimeEndtimeLog

time用于启动一个计时器;timeEnd用于停止计时器;timeLog则用于在这个计时器期间打印其他的带计时功能的日志。这三个方法是搭配使用的。举个例子,运行如下的代码:

let sum = 0;
console.time('count')
for (let i = 0; i < 10000; i++) {
  if (i % 1000 === 0){
    console.timeLog('count', `在${i}处花费的时间`)
  }
  sum += i
}
console.timeEnd('count')

运行结果如下所示: time.png

count一样,这三个方法都可以传入一个字符串用于标记该计时器,比如上面例子中的count,如果不传的话,默认是default

⑥、trace

trace用于打印堆栈信息,举个例子:

const first = () => {
  second() 
};
const second = () => { 
  third()
};
const third = () => { 
  console.trace()
};
first();

执行上面的代码,可以看到当前的调用栈信息: track.png

Verbose

  • debug

info一样,debuglog也是等价的,唯一的区别是debug的级别属于verbose,所以在默认情况下,在控制台用console.debug输出一个信息,默认是看不到这个输出信息的,需要调整日志的过滤级别,如下图所示: debugLevel.gif

ErrorWarn

warnerror就不细说了,平时开发中见过太多了💔,希望大家在以后的开发过程中无error,无warn🙏

捎带提一下assert,它属于Error级别,如果断言是true,则控制台无输出,如果断言是false,那么控制台会输出一个error级别的信息,如下图所示: assert.png

非日志

①、clear

clear用于清除控制台的输出,和下图中左上角的清除图标一样的效果,两者的区别是:当Console面板的Setting中勾选了Preserve log的时候,clear方法是失效的,清除不了控制台的输出;但是点击清除的图标则是可以清除成功的,如下图所示: image.png

②、groupgroupEndgroupCollapsed

这三个方法都是用于对输出的信息进行分组,如下图所示: group.png

groupgroupCollapsed的区别在于:初始情况下,groupCollapsed是将信息折叠起来的,需要手动点击展开。

③、context

在控制台打印console.context(),可以看到如下图所示: context.png 乍一看,和console相等,其实它的返回值就是console的子集,缺少了memory属性和context方法。

④、memory

memory是一个属性,可以查看当前的内存信息,如下图所示: memory.png jsHeapSizeLimit:上下文内可用堆的最大体积,单位是字节。

totalJSHeapSize: 已分配的堆体积,单位是字节。

usedJSHeapSize: 已使用的堆内存,单位是字节。

三者之间的关系是:jsHeapSizeLimit >= totalJSHeapSize >= usedJSHeapSize

ps: jsHeapSizeLimit应该是操作系统根据机器的内存大小分配给浏览器中的JS对象可以使用的最大空间,小样本范围测试了下,jsHeapSizeLimit的大小和操作系统、浏览器均无关系,只和机器的内存有关。16G的机器的jsHeapSizeLimit3.5G左右,而8G的机器分配的jsHeapSizeLimit2G左右。

⑤、profileprofileEnd

profileprofileEnd是用于性能分析的,运行下面的代码:

let arr = new Array(100000).fill(1)                               
function A () {
  for (let i = 0; i < arr.length; i++) {}
}

function B () {
  for (let i = 0; i < arr.length; i++) {}
  C();
}

function C () {
  for (let i = 0; i < arr.length; i++) {}
}

function fun () {
  console.profile('loop');
  A();
  B();
  console.profileEnd('loop');
}

fun();

在控制台可以看到如下输出: profile_console.pngJavaScript Profile面板中可以找到该性能报告: profile.png 在上面的性能报告中,可以看到函数调用栈和每个函数的执行时间。 Self Time:表示当前函数自身运行耗时,不包括当前函数中调用的其他函数运行耗时。 Total Time:表示当前函数运行总耗时,包括了自身运行耗时+函数内部调用的其他函数的运行耗时。

ps: 不是标准特性,不要在生产环境使用。而且在上面的demo中,如果数组的长度不够的话,性能报告里面是看不到该方法的执行时间的。

⑥、timeStamp

timeStamp用于向Performance面板添加一个标记来进行调试,放到以后的Performance面板来讲解。

ps:这是一个非标准特性,不要在生产环境使用。

运行JavaScript

控制台是一个REPL,比如你在控制台输入2 + 5,回车之后马上就可以得到结果7

psREPL: Read(读取)-Eval(执行)-Print(输出)-Loop(循环),一般翻译成:交互式解释器

控制台设置

console_settings.png

Hide network

不勾选Hide network的时候,如果网络请求有错误的时候,是会在控制台输出错误日志的,如果勾选了该选项,将会隐藏这些错误信息,如下: hideNetwork.gif

Preserve log

默认情况下,每次刷新页面的时候,console下的输出都会被清除,如果想要不清除之前的输出,可以启用Preserve log,如下: preserveLog.gif

Selected context only

和顶部的上下文选择配合使用,用于筛选日志。 selectedContextOnly.gif

Group similar message in console

将相同的日志分组,如下所示: groupSimilarMsg.gif

Log XMLHttpRequests

勾选了Log XMLHttpRequests,可以看到所有xhr请求的日志,点开其中某个xhr的日志,还可以看到完整的调用栈。如下图所示: image.png ps: 还记得之前的Hide network吗?如果这两个选项同时开启会怎么样?

Eager evaluation

提早评估,如下: eagerEvaluation.gif

Autocomplete from history

根据日志自动补全,如下图所示: autoComplete.png 上图中蓝色箭头开头的,也就是框出来的部分就是之前输入的历史记录。

Evaluate triggers user activate

有些js api无法通过代码直接调用,比如window.open(),需要开启该选项才能调用。 evaluateTrigger.gif

使用介绍

选择执行上下文

如下图所示,点击top右侧的下拉箭头可以选择当前console所在的执行环境,默认是top,表示的是页面的顶部框架。比如在paasdev.kdcloud.comtop指的是控制台。而控制台中的每个服务的图表是以iframe的形式嵌套进来的,点击下拉框的箭头可以选择切换当前console的执行环境。 image.png 在控制台和容器的index.html上有后端设置的模板变量PUBLICPUBLIC是全局变量,直接挂载在window上,比如控制台的window上的PUBLIC我们可以通过如下方式查看: image.png 那容器上的PUBLICconsole面板下怎么查看呢?可以通过切换执行上下文来查看,如下图所示: image.png

创建实时表达式

如下图所示,点击眼睛图标可以创建一个表达式,实时监测表达式的值。 image.png 举个例子,创建了一个实时表达式document.body.clientWidth,当修改窗口的大小的时候,如下图所示,该表达式的值在实时变化。 liveExpression.gif ps: 执行频率是250毫秒。

日志过滤

根据执行上下文过滤

先点击top选择要显示日志的执行上下文,然后在console settings中勾选Selected context only即可。

按照日志级别过滤

如下图所示: filterLogByLevel.gif

点击侧边栏也可以根据日志级别进行过滤: image.png

需要注意的是,当打开了侧边栏的时候,顶部的过滤下拉框是置灰的。如果只想查看来自本网页的消息,可以点击user messages

根据关键字或者正则过滤

如下图所示: filterLogByReg.gif

根据url过滤

在输入框中输入要url:目标url即可,如下所示: filterLogByUrl.gif 如果是不需要显示某个url的消息,则输入-url:目标url

隐藏的常量和方法

$_

返回最近的表达式的值 $_.png

$0-$4

返回最后五个在Element中选中的DOM元素或者是在Memory面板中选中的JS堆栈对象。$0表示最近的一个,以此类推。 0-4.gif

$(selector[, startNode])

该函数等价于document.querySelector()startNode的默认值是document,指定查找的范围。 $(selector).gif

$$(selector[,startNode])

该函数等价于document.querySelectorAll()$$(selector).gif

$x(path[, startNode])

返回满足pathDOM元素数组 image.png

copy(object)

使用copy(obj)可以将对象复制到粘贴板。

const data = [{
    name: 'hello',
    age: 10
}, {
    name: 'world',
    age: 20
}]
copy(data)

debug(function)undebug(function)

当你想要给某个函数打断点的时候,可以使用debug(function),当该函数调用的时候,将暂停在函数体的第一行,例子如下:

function add(a, b) {
  return result
}
debug(add)
add() 

其实上面的代码也就等价于:

function add(a, b) {
  debugger
  return result
}
add() 

undebug(function)用于取消函数断点

getEventListeners(object)

返回参数object上注册的事件,如下图所示: image.png 也可以通过ctrl+shift+p调出命令行,输入show Event Listeners查看选中的元素上绑定的事件,如下图所示: image.png 勾选Ancestors可以查看该元素继承来自父组件的事件。点击事件右侧的Remove可以移除该事件。

monitor(function)unmonitor(function)

monitor用于监听函数,unmonitor用于取消函数监听,如下图所示: monitor.png

monitorEvents(object[, event])unmonitorEvents(object[, event])

monitorEvents用于监听object上的单个事件、多个事件或者事件类型。unmonitorEvents用于取消object上的事件监听。

# 监听单个事件
monitorEvents(document.querySelector('a'), 'click') 
# 监听多个事件
monitorEvents(document.querySelector('a'), ['click', 'mousemove'])
# 监听一种事件类型
monitorEvents(document.querySelector('a'), 'mouse')

其中入参的事件名称和事件类型如下图所示: 事件类型.png 举个例子: monitorEvents.gif

其他

有时候开发过程中我们需要临时测试一下第三方包的功能,比如想用下moment,这种情况下我们可以直接在console中测试,只需要安装一个插件Console Importer: console_importer插件.png 通过$i(包名)加载进来就可以使用了: image.png