这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
前言
作为前端开发者,写Bug是日常习惯,但是只写不行,还要去发现它,所以就要去调试代码。调试代码时采用方式有两种,一种是debugger(断点调试),另一种是console.log(日志调试)。
作为初学者,最先学会的就是日志调试,但是你真的懂console.log的使用吗?
本文主要讲解console对象的其他方法、console.log的彩色输出、console.log在谷歌浏览器打印引用类型的显示bug、。
console的家族成员
console对象本身不是W3C标准提出的,所以每个浏览器都有自己的实现,我们主要研究谷歌浏览器的console对象。
打开浏览器控制台,输入console
可以看出它除了我们常用的log方法,还有info、debug、warn、error、count、time等方法,因为方法很多,所以只会挑几个特殊的方法讲。如果想知道更多方法的使用方式,可以参考MDN的文档。
log相似方法
和log方法功能相似的还有info、debug、warn、error,它们的主要目的就是输出调试信息。
可以看出,不同的方法之间的差异体现在颜色和背景,就是方便开发者去区分。
因为error方法的颜色比较醒目,在我们开发过程中,如果想在多个log之中找到输出信息就可以使用error方法
time代码性能检测
在我们开发或学习过程中,常常会去看某一串代码在运行时所需要的时间,我们可能常用的方法时前后时间戳,然后做运算,但是这样不够简便。
console.time和console.timeEnd解决了这种写法
console.time(1)
var knum = 0;
for (var i = 0; i < 10000; i++)
{
knum /= i;
}
console.timeEnd(1) //1: 7.7138671875 ms
console.time和console.timeEnd不仅要成对出现,并且相匹配的console.time和console.timeEnd传递的参数必须一样
dir输出对象真实结构
let appHtml=document.getElementById("app")
console.log(appHtml)
在我们调试输出Dom元素时,控制台却显示HTML的结构,但是往往我们需要的是Dom对象的属性列表,这个时候console.dir,他和控制台的 dir方法一样,可以获取Dom对象的属性列表
trace输出函数执行堆栈
在我们不知道当前执行函数在那个函数中执行,或者不确定函数执行的层级顺序就可以使用trace来查看函数调用栈
function a() {
console.log('a函数')
console.trace()
}
function b() {
console.log('b函数')
a()
}
b()
给console.log添加颜色
我们在浏览一些网站时,会发现它的控制台打印出一些色彩鲜艳的文字,比如淘宝
在我们平时的log输出中是看不到的,那么他又是怎么去实现的喃?
// 1. 将css样式内容放入数组
const styles = [
'color: red',
'font-size: 46px',
'text-shadow: 2px 2px 2px black',
'padding: 10px',
].join(';');
// 2. 利用join方法讲各项以分号连接成一串字符串
// 3. 传入styles变量
console.log('%c安全警告', styles);
%c就是格式占位符,它的意思可以理解为先占用字符串一个位置,然后由后面的参数来补充这个位置,类似于C语言的格式占位符。
除了它还有%s、%f、 %d等。
console.log("Foo %.2f", 1.1) //%.2f代表当前位置插入数据为保留两位小数的浮点数,输出:Foo 1.10
console.log("%s",'Foo') //%s 代表当前位置插入数据为字符串,输出:Foo
console.log("Foo %d", 1.1) //%d 代表当前位置插入数据为整数,输出:1
console.log 输出引用类型异常
现象
let obj={
age:11
}
console.log(obj) //改变前
obj.age=999
console.log(obj) //改变后
可以看到改变前和改变后的输出,在最外层快照是不一样的,但是点击查看详情两个输出却是一样的,这就牵连 到谷歌浏览器的一个Bug。
对于引用类型,浏览器会先显示一个最外层快照,并且保存这个对象的引用,当我们点击这个对象的时候,会去访问这个引用。所以就造成点击对象时两次输出时一样的结果,因为对象时引用类型,无论访问前还是访问后地址都没变,所以访问相同的堆信息数据。
解决办法
-
深拷贝
let obj={ age:11 } console.log(JSON.parse(JSON.stringify(obj))) //改变前 obj.age=999 console.log(JSON.parse(JSON.stringify(obj))) //改变后 -
转为字符串
let obj={ age:11 } console.log(JSON.stringify(obj,null,2)) //改变前 obj.age=999 console.log(JSON.stringify(obj,null,2)) //改变后 -
debugger模式调试代码
内存溢出
因为在console.log输出会保存引用类型的地址,所以这个引用类型时不会被垃圾回收机制给清除了。这样做的结果会造成内存溢出,看下面代码
function Test() {
this.a = new Array(10000).fill('isboyjc')
console.log(this)
}
for (let i = 0; i < 100; i++) {
new Test();
}
运行上面的代码,通过谷歌Performance去分析,发现内存的消耗时一直往上的,说明内存一直被占用,那是因为console.log输出会保存输出的引用类型的指针,造成垃圾回收机制不去回收,内存一直被占用,所以在日常开发过程中,一定要删除不要的log日志。