控制台有两个主要用途: 查看日志和运行JavaScript
。
查看日志
平时在开发过程中,我们总是借助console
来辅助调试,那么console
是个什么东西呢?我们可以在Console
面板打印下看看。
可以看到console
对象上有很多方法,总的来说可以分为两大类,日志和非日志。
日志
DevTools
给console
中的打印日志的方法定义了四个级别,分别是Verbose
、Info
、Warning
和Error
。如下表格所示:
级别 | 方法 |
---|---|
Verbose | debug |
Info | log、info、count、countReset、dir、dirxml、table、time、timeEnd、trace |
Warning | warn |
Error | error、assert |
在控制台我们也可以通过日志级别来过滤日志,如下图所示:
下面来看下这些方法的使用:
Info
①、log
和info
日常开发中使用最多的就是log
了,info
与它等价。如果有需要的话,也可以设置输出日志的样式,比如console.log('%c hello word', 'color: red; font-size: 30px')
。如下图所示:
如果想要输出的日志带上时间,可以shift
+ctrl
+ p
调出命令行,在上面的输入框中输入show time
,然后选中show timestamps
即可。
用log
输出对象的时候需要注意一个小细节,参考如下demo
:
obj
的值是在第五行修改的,但是在第四行的时候打印出的obj
的值,已经是修改后的值了,这是因为当我们手动展开该变量的时候,控制台才获取该变量的值。如果想要在第四行准确输出obj
的值,可以使用console.log(JSON.stringify(obj))
输出。
②、count
和countReset
count
和countReset
是配套使用的,用于计数和重置计数。举个例子,在下面的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开始了
③、dir
与dirxml
dir
用于打印一个对象的属性和方法,而dirxml
则用于打印DOM
节点。如下图所示:
ps
:dir
与dirxml
都是非标准特性。
④、table
table
用于打印一个数组中的数据,如下图所示:
如果只需要显示一列或者某几列,可以使用第二个可选参数来指定需要展示的列,如下图所示:
⑤、time
、timeEnd
和timeLog
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')
运行结果如下所示:
和count
一样,这三个方法都可以传入一个字符串用于标记该计时器,比如上面例子中的count
,如果不传的话,默认是default
。
⑥、trace
trace
用于打印堆栈信息,举个例子:
const first = () => {
second()
};
const second = () => {
third()
};
const third = () => {
console.trace()
};
first();
执行上面的代码,可以看到当前的调用栈信息:
Verbose
debug
和info
一样,debug
和log
也是等价的,唯一的区别是debug
的级别属于verbose
,所以在默认情况下,在控制台用console.debug
输出一个信息,默认是看不到这个输出信息的,需要调整日志的过滤级别,如下图所示:
Error
和Warn
warn
和error
就不细说了,平时开发中见过太多了💔,希望大家在以后的开发过程中无error
,无warn
🙏
捎带提一下assert
,它属于Error
级别,如果断言是true
,则控制台无输出,如果断言是false
,那么控制台会输出一个error
级别的信息,如下图所示:
非日志
①、clear
clear
用于清除控制台的输出,和下图中左上角的清除图标一样的效果,两者的区别是:当Console
面板的Setting
中勾选了Preserve log
的时候,clear
方法是失效的,清除不了控制台的输出;但是点击清除的图标则是可以清除成功的,如下图所示:
②、group
、groupEnd
和groupCollapsed
这三个方法都是用于对输出的信息进行分组,如下图所示:
group
和groupCollapsed
的区别在于:初始情况下,groupCollapsed
是将信息折叠起来的,需要手动点击展开。
③、context
在控制台打印console.context()
,可以看到如下图所示:
乍一看,和console
相等,其实它的返回值就是console
的子集,缺少了memory
属性和context
方法。
④、memory
memory
是一个属性,可以查看当前的内存信息,如下图所示:
jsHeapSizeLimit
:上下文内可用堆的最大体积,单位是字节。
totalJSHeapSize
: 已分配的堆体积,单位是字节。
usedJSHeapSize
: 已使用的堆内存,单位是字节。
三者之间的关系是:jsHeapSizeLimit
>= totalJSHeapSize
>= usedJSHeapSize
ps
: jsHeapSizeLimit
应该是操作系统根据机器的内存大小分配给浏览器中的JS
对象可以使用的最大空间,小样本范围测试了下,jsHeapSizeLimit
的大小和操作系统、浏览器均无关系,只和机器的内存有关。16G
的机器的jsHeapSizeLimit
是3.5G
左右,而8G
的机器分配的jsHeapSizeLimit
是2G
左右。
⑤、profile
和profileEnd
profile
和profileEnd
是用于性能分析的,运行下面的代码:
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();
在控制台可以看到如下输出:
在JavaScript Profile
面板中可以找到该性能报告:
在上面的性能报告中,可以看到函数调用栈和每个函数的执行时间。
Self Time
:表示当前函数自身运行耗时,不包括当前函数中调用的其他函数运行耗时。
Total Time
:表示当前函数运行总耗时,包括了自身运行耗时+函数内部调用的其他函数的运行耗时。
ps
: 不是标准特性,不要在生产环境使用。而且在上面的demo
中,如果数组的长度不够的话,性能报告里面是看不到该方法的执行时间的。
⑥、timeStamp
timeStamp
用于向Performance
面板添加一个标记来进行调试,放到以后的Performance
面板来讲解。
ps
:这是一个非标准特性,不要在生产环境使用。
运行JavaScript
控制台是一个REPL
,比如你在控制台输入2 + 5
,回车之后马上就可以得到结果7
。
ps
:REPL
: Read(读取)-Eval(执行)-Print(输出)-Loop(循环)
,一般翻译成:交互式解释器
控制台设置
Hide network
不勾选Hide network
的时候,如果网络请求有错误的时候,是会在控制台输出错误日志的,如果勾选了该选项,将会隐藏这些错误信息,如下:
Preserve log
默认情况下,每次刷新页面的时候,console
下的输出都会被清除,如果想要不清除之前的输出,可以启用Preserve log
,如下:
Selected context only
和顶部的上下文选择配合使用,用于筛选日志。
Group similar message in console
将相同的日志分组,如下所示:
Log XMLHttpRequests
勾选了Log XMLHttpRequests
,可以看到所有xhr
请求的日志,点开其中某个xhr
的日志,还可以看到完整的调用栈。如下图所示:
ps
: 还记得之前的Hide network
吗?如果这两个选项同时开启会怎么样?
Eager evaluation
提早评估,如下:
Autocomplete from history
根据日志自动补全,如下图所示: 上图中蓝色箭头开头的,也就是框出来的部分就是之前输入的历史记录。
Evaluate triggers user activate
有些js api
无法通过代码直接调用,比如window.open()
,需要开启该选项才能调用。
使用介绍
选择执行上下文
如下图所示,点击top
右侧的下拉箭头可以选择当前console
所在的执行环境,默认是top
,表示的是页面的顶部框架。比如在paasdev.kdcloud.com
中top
指的是控制台。而控制台中的每个服务的图表是以iframe
的形式嵌套进来的,点击下拉框的箭头可以选择切换当前console
的执行环境。
在控制台和容器的index.html
上有后端设置的模板变量PUBLIC
,PUBLIC
是全局变量,直接挂载在window
上,比如控制台的window
上的PUBLIC
我们可以通过如下方式查看:
那容器上的PUBLIC
在console
面板下怎么查看呢?可以通过切换执行上下文来查看,如下图所示:
创建实时表达式
如下图所示,点击眼睛图标可以创建一个表达式,实时监测表达式的值。
举个例子,创建了一个实时表达式document.body.clientWidth
,当修改窗口的大小的时候,如下图所示,该表达式的值在实时变化。
ps
: 执行频率是250
毫秒。
日志过滤
根据执行上下文过滤
先点击top
选择要显示日志的执行上下文,然后在console settings
中勾选Selected context only
即可。
按照日志级别过滤
如下图所示:
点击侧边栏也可以根据日志级别进行过滤:
需要注意的是,当打开了侧边栏的时候,顶部的过滤下拉框是置灰的。如果只想查看来自本网页的消息,可以点击user messages
。
根据关键字或者正则过滤
如下图所示:
根据url
过滤
在输入框中输入要url:目标url
即可,如下所示:
如果是不需要显示某个url
的消息,则输入-url:目标url
。
隐藏的常量和方法
$_
返回最近的表达式的值
$0-$4
返回最后五个在Element
中选中的DOM
元素或者是在Memory
面板中选中的JS
堆栈对象。$0
表示最近的一个,以此类推。
$(selector[, startNode])
该函数等价于document.querySelector()
,startNode
的默认值是document
,指定查找的范围。
$$(selector[,startNode])
该函数等价于document.querySelectorAll()
。
$x(path[, startNode])
返回满足path
的DOM
元素数组
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
上注册的事件,如下图所示:
也可以通过ctrl
+shift
+p
调出命令行,输入show Event Listeners
查看选中的元素上绑定的事件,如下图所示:
勾选Ancestors
可以查看该元素继承来自父组件的事件。点击事件右侧的Remove
可以移除该事件。
monitor(function)
和unmonitor(function)
monitor
用于监听函数,unmonitor
用于取消函数监听,如下图所示:
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')
其中入参的事件名称和事件类型如下图所示: 举个例子:
其他
有时候开发过程中我们需要临时测试一下第三方包的功能,比如想用下moment
,这种情况下我们可以直接在console
中测试,只需要安装一个插件Console Importer
:
通过$i(包名)
加载进来就可以使用了: