此為轉(zhuǎn)載文章,原文鏈接在底部~
我們在控制臺打印一下console,看看它還有哪些神奇的方法:

下面我們從最簡單的console.log方法開始,逐個分析其他方法以及所涉及到的調(diào)試技巧。
一、console.log()打印內(nèi)容。
此處:主要聊一聊console.log()的占位符。其共有五種占位符
- %s 字符串
- %d 或 %i 整數(shù)
- %f 浮點數(shù)
- %o 對象的鏈接
- %c CSS格式字符串
如果方法的第一個參數(shù)中使用了占位符,那么就依次使用后面的參數(shù)進行替換。
const name = 'chinaBerg';
const age = 88;
const money = 12.88;
const obj = {
status: '很積極'
}
console.log('我叫%s,%d歲,有%f元,狀態(tài):%o', name, age, money, obj.status, '又打印一句話')

可以看到我們后面使用的參數(shù)對前面的占位符進行了替換,有點像我們字符串拼接的簡化操作。比如我們es5中的字符串拼接:
console.log('我叫' + name + ' ,' + age +'歲,有' + money + '元')
es6已經(jīng)有了更強悍的字符串模板:
console.log(`我叫${name},${age}歲, 有${money}元`);
es6的字符串模板中,只能使用%c占位符,其他占位符是沒有效果的。
// 注意這里字符串模板的最后插入了%f
console.log(`我叫${name},${age}歲, 有%f元`, 12.88);

%c占位符還是略有趣味的:
const css1 = 'font-size: 22px;font-weight: bold';
const css2 = 'border: 1px solid green';
const css3 = 'color: #fff;background: #f00';
// 占位符填入
console.log('%c %s + %s = %s', css1, 1, 2, 3);
// 字符串拼接形式中插入%c占位符
console.log('%c我的名字叫' + name + ', 今年' + age + '歲', css2);
// es6字符串模板中插入%c占位符
console.log(`%c我叫${name},${age}歲, 有%f元`, css3);

可以看到這些打印的內(nèi)容已經(jīng)被添加了我們的樣式。
二、console.info()和console.debug()
和console.log()很像的還有倆,一個是console.info(),一個是console.debug()。其實這個三個功能都是一樣的,只不過有些區(qū)別,下面就具體介紹一下這三個方法。
console.log('我是console.log()打印出來的');
console.info('我是console.info()打印出來的');
console.debug('console.debug()打印出來的')



-
console.log()方法,無論哪個瀏覽器,打印出的效果都是一樣的。 -
console.info()方法,ie沒有打印出來,即不支持這個屬性。但是在谷歌和火狐上又略有區(qū)別:打印的結(jié)果是一樣的,但是火狐控制臺上,會在打印的結(jié)果前面添加一個類似i的小符號。 -
console.debug()方法,谷歌和opera是不支持的,ie和火狐是支持的。
所以呢,既然三個方法功能是基本一樣的,我們?nèi)绻幌氪蛴∫恍﹥?nèi)容的話,還是老老實實的使用console.log()穩(wěn)一點。當(dāng)然了,這也抵不住你就使用火狐來debug呢!可是,考慮到如果你的代碼庫的某些打印信息需要給別的開發(fā)者看的話,還是用兼容性更好的穩(wěn)一些。
補充修正:chrome并不是不支持console.debug,只是默認(rèn)日志級別不打印調(diào)試信息,把verbose勾上就好了
三、console.clear()
清除控制臺打印的內(nèi)容,并將光標(biāo)回歸到第一行

和我們點擊控制臺的這個清除按鈕的效果一樣
四、console.assert(表達式 [,arg1, arg2……argn])打印斷言
第一個參數(shù)是用來判斷是否打印斷言的表達式,只有當(dāng)表達式的值為false的時候,才會打印后續(xù)的參數(shù):
const arr = [1, 2, 3];
// 打印斷言,如果arr[0]的值不等于2,則打印提示信息
console.assert(arr[0] === 2, 'arr[0]的值不等于2');


- 客戶端的
console.assert()打印斷言,并不會阻塞后續(xù)代碼的執(zhí)行,只是在斷言的表達式為false的時候,向控制臺打印你的內(nèi)容。 - 而在
node.js中,值為假的斷言將會導(dǎo)致一個AssertionError被拋出,使得代碼執(zhí)行被打斷。這兩者是有區(qū)別的。
五、console.count() 打印計數(shù)
輸出他被調(diào)用了多少次。
傳遞一個參數(shù)作為計數(shù)提示:
for (let i = 0; i < 10; i++) {
console.count('我被調(diào)用了');
}

簡單修改一下:
for (let i = 0; i < 10; i++) {
console.count(`我是${i}我被調(diào)用了`);
}

這個方法意思就是:向控制臺寫入在同一行使用相同標(biāo)簽調(diào)用
count()的次數(shù)。
就是如果你給count()傳遞的參數(shù)值不一樣,那么是分開計數(shù)的。
再看一個簡單的示例:
function fun (name) {
console.count(name)
}
fun('小米');
fun('小剛');
fun('小米');

如果不傳遞參數(shù),默認(rèn)的計數(shù)提示標(biāo)簽是default字符串:
for (let i = 0; i < 10; i++) {
// count()沒傳遞提示標(biāo)簽
console.count();
}

一般在某些循環(huán)中,如果我們想知道一個函數(shù)或者變量被執(zhí)行或者調(diào)用了多少次的時候,可以使用
console.count()方法,而通過傳遞提示標(biāo)簽,我們更可以清晰的知道一個函數(shù)分別被不同的情況調(diào)用了幾次,從而幫助我們定位錯誤信息。
六、console.time()和console.timeEnd()打印計時
用來跟蹤某一個操作的占用時長。
每一個計時器必須擁有唯一的名字,time()的參數(shù)名和timeEnd()的參數(shù)名要一樣。
可以沒有參數(shù),默認(rèn)計時提示為default
// 立即啟動計時器
console.time()
// 某些操作
for (let i = 0; i < 10000; i++) {
// 某些操作
}
// 立即結(jié)束計時器,并輸出計時結(jié)果
console.timeEnd()

傳遞計時器提示:
// 立即啟動計時器
console.time('time')
// 某些操作
for (let i = 0; i < 10000; i++) {
// 某些操作
}
// 立即結(jié)束計時器,并輸出計時結(jié)果
console.timeEnd('time')

- 頁面中最多能同時運行10,000個計時器
- 該方法并不會將結(jié)算結(jié)果返回到j(luò)s中,而只是能打印在控制臺上。所以不能使用此方法在js中來作為普通計時器使用或者進行性能收集器的一部分。
七、console.dir() 輸出以 JavaScript 形式表示的指定對象
如果正在記錄的對象是 HTML 元素,將輸出其以 DOM 形式表示的屬性。
打印一個對象:
// 一個對象
const obj = {
name: '某某渣',
age: 22,
sex: '男'
}
// dir打印
console.dir(obj);
// log打印
console.log(obj);

對于對象或者json等,console.log()和console.dir()效果基本一樣。
但是如果打印的是一個dom元素:
// dir打印
console.dir(document.body);
// log打印
console.log(document.body)
console.dir()會將dom的所有屬性和事件都被打印出來:

console.log()打印的就是dom:
八、console.dirxml(object)
如果可以,輸出 object 子級元素的 XML 表示形式,否則輸出其 JavaScript 表示形式。
在 HTML 和 XML 元素上調(diào)用 console.dirxml() 等同于調(diào)用console.log()。
九、console.group() + console.groupEnd()
將控制臺輸出的內(nèi)容進行分組
將打印的信息歸類分組打印,并且可以展開、折疊。
這在輸出大量數(shù)據(jù)的或許有用。
// console.groupCollapsed() + console.groupEnd()的形式,默認(rèn)是折疊的
console.group('分第一組');
console.log('html')
console.dir({ type: '前端'}),
console.groupEnd('分第一組')
// console.group() + console.groupEnd() 默認(rèn)是展開的
console.group('分第2組');
console.log('php')
console.dir({ type: '后臺'}),
console.groupEnd('分第2組')

十、console.table()
可以將數(shù)組、對象等復(fù)雜類型的數(shù)據(jù)打印成表格的形式
打印簡單的數(shù)組:
const arr = ['a', 'b'];
console.table(arr)

打印復(fù)雜的數(shù)組:
const arr = [
{
name: '小明',
age: 22,
likes: ['跳舞', '上網(wǎng)']
},
{
name: '小剛',
age: 23,
likes: ['擼碼', '計算機']
}
];
console.table(arr)

打印對象:
const obj = {
name: '小明',
age: 22,
likes: [
{
a: 1,
b: 2
},
{
a: 3,
b: 4
},
]
}
console.table(obj)

十一、console.trace()
堆棧中調(diào)用此方法的路徑
如果想要清楚地知道一個函數(shù)的調(diào)用軌跡,可以將此方法寫在函數(shù)內(nèi)部,便可以跟蹤函數(shù)的調(diào)用軌跡,代碼實現(xiàn)如下:
function test(name) {
console.trace(`此處調(diào)用了${name}`)
}
function doSome (name) {
test(name);
}
doSome('翠花');

此處打印出了js中調(diào)用test()的所有堆棧位置。從上到下依次為最里層的調(diào)用一直到最外層調(diào)用。平時我們使用第三方庫的時候,如果寫法不對,經(jīng)??梢栽诳刂婆_看到我們的報錯信息,并且像這樣打印出了錯誤位置的堆棧信息。
十二、console.warn()
打印一條警告信息
console.warn('我是一條警告')

十三、console.error()打印錯誤
console.error('我這里出現(xiàn)了錯誤,我來告知用戶')

該方法主要用來打印錯誤,打印結(jié)果的樣式如上圖。也沒什么好說的,不過如果你開發(fā)第三方庫的時候,可以用到。但是
throw拋出錯誤的方式也會用到不少。
十四、console.profile() 和 console.profileEnd()
新建一個性能分析器(基于cpu的使用情況)。用于函數(shù)性能分析的利器。
相對于復(fù)雜邏輯的JavaScript程序調(diào)優(yōu),console.profile() 和 console.profileEnd()新建性能分析器便派上用場
用法和time的一樣,console.profile()開始,console.profileEnd()結(jié)束,需要傳遞一個參數(shù)作為標(biāo)簽使用,說俗了點就是為這個性能分析器起個名字。看下如下代碼,我們測試幾種不同for循環(huán)書寫方式的耗時情況:
// 簡單新建一個數(shù)組吧,新建一個一千萬個成員為1的數(shù)組
let arr = new Array(10000000).fill(1);
// 第一種for循環(huán)書寫方式
function fun1 () {
for (let i = 0, len = arr.length; i < len; i++) {}
}
// 第二種for循環(huán)書寫方式
function fun2 () {
for (let i = arr.length; i --; ) {}
fun1();
}
// 第三種for循環(huán)書寫方式
function fun3 () {
for (let i = 0, item; item = arr[i++]; ) {}
}
// 執(zhí)行三個函數(shù)
function fun () {
fun1();
fun2();
fun3();
}
// 立即開始一個性能分析器
console.profile('測試for循環(huán)');
fun();
//
console.profileEnd('測試for循環(huán)');

在javascript Profiler面板中,打開性能分析器

如果你沒有上面紅框標(biāo)識的面板,那么點擊右邊的三個點,在下拉菜單中依次選擇More tools -> JavaScript Profiler選項,就可以將該選項添加到上面的紅框位置。然后點擊該面板,進入對應(yīng)內(nèi)容:

然后我們點開每一個函數(shù)看下具體的情況:

- 1處,
Self Time表示當(dāng)前函數(shù)自身運行耗時,什么意思?就是說當(dāng)前函數(shù)自身執(zhí)行耗時,不包括當(dāng)前函數(shù)中調(diào)用的其他函數(shù)運行耗時。 - 2處,
Total Time表示當(dāng)前函數(shù)運行總耗時,包括了自身運行耗時+函數(shù)內(nèi)部調(diào)用的其他函數(shù)的執(zhí)行耗時。 -
Function那一列,我們通過上圖打開的fun1那一欄說明,fun1展開后的結(jié)果包括fun和fun2,這指的是函數(shù)fun1在函數(shù)fun和fun2中被調(diào)用執(zhí)行的耗時。通過代碼我們知道,fun1函數(shù)確實在fun函數(shù)和fun2個被調(diào)用過1次,所以這里展示了fun在這兩處被調(diào)用執(zhí)行的耗時時間。 - 每個函數(shù)行最右邊還有會堆棧位置,點擊即可進入
resouce面板中該函數(shù)所在的文件位置。
如果你關(guān)注fun1函數(shù)的執(zhí)行時間,你可以點擊選中fun1這一行,然后點擊上面的眼睛圖標(biāo),將自動只為你展現(xiàn)fun1函數(shù)的信息:

- 選中函數(shù)行,點擊眼睛即針對性的展示當(dāng)前函數(shù)。
- 選中函數(shù)和,如果點擊×號,將會刪除當(dāng)前函數(shù)行。
- 選中函數(shù)行點擊眼睛進入后,如果想返回到上述全部函數(shù)行的面板,可以點擊上圖刷新按鈕?;蛘邉h除了函數(shù)行后也可以恢復(fù)如上圖。
- 上圖三個按鈕只有在顏色變深的時候才可點擊,眼睛和×號只有在選中函數(shù)行的情況下可點,刷新按鈕在進入或者刪除函數(shù)行之后可以點。
還有一點沒介紹,就是該這種數(shù)據(jù)展示方式,是默認(rèn)的方式:Heavy(Bottom Up),即將所有執(zhí)行的函數(shù),按照耗時長度,從上到下降序排列,耗時的在最上面,不耗時的在最下面。但是他還有另外兩種方式(Chart和 Tree),如下圖:


將每個函數(shù)行打開后,顯示了該函數(shù)所調(diào)用的函數(shù)。這種數(shù)據(jù)分析的展示方式其實是,先展示最外層的函數(shù),展開后,顯示該函數(shù)所調(diào)用的所有函數(shù),依次往里類推。每一行都展示該函數(shù)執(zhí)行的耗時。其他操作同上。

- 上部分藍色區(qū)域為cpu占用的大體走勢圖,可以清晰地看到每個時間節(jié)點的cpu占用情況,是高是低一目了然。
- 下半部分為每個函數(shù)開始運行的時間節(jié)點。
如果點擊上部分藍色區(qū)域,還可以更細(xì)粒度查看當(dāng)前事件的函數(shù)運行情況(在當(dāng)前時間節(jié)點劃分為更細(xì)的力度),如下圖:

鼠標(biāo)移入某個函數(shù),還可以看到當(dāng)前函數(shù)所運行的耗時情況,如下圖:

console.profile() 和 console.profileEnd()函數(shù)性能分析器的建立,給我們分析函數(shù)性能帶來的非常大的便利,這對于我們檢測程序運行瓶頸非常有幫助。
十五、console.timeStamp('事件信息')
在Performance(以前叫Timeline)性能面板中的會話錄制期間插入一條添加一個事件。
說到這個console.timeStamp()方法,這個方法在我們進行性能調(diào)試的時候會用到。說到這個方法首先要提到Performance性能面板,因為該方法打印出來的結(jié)果需要在這個調(diào)試面板中查看,準(zhǔn)確的來說,該方法是配合性能面板來調(diào)試的:
在Perdormance面板中,我們可以分析當(dāng)前頁面的性能,可以得知頁面加載和用戶交互相關(guān)的事件分析結(jié)果。關(guān)于Performance這塊的內(nèi)容,如果仔細(xì)說起來,內(nèi)容是比較多的。這里暫且只介紹和console.timeStamp方法相關(guān)的內(nèi)容。以后可以單獨把這塊拿出來細(xì)細(xì)分析和記錄。
console.timeStamp可以在時間軸上寫入一個事件:
// 一些其他操作
for (let i = 0; i < 10000; i ++) {}
// 在錄制會話期間插入的第一個事件
console.timeStamp('第一個循環(huán)完了')
// 一些其他操作
for (let i = 0; i < 10000; i ++) {}
// 在錄制會話起價插入的第二個事件
console.timeStamp('第2個循環(huán)完了')
錄制完會話后,我們輸入移入下圖紅框左上方的黃色豎線上可以看到彈出一個提示框,上面標(biāo)注了Timestamp提示:‘第一個循環(huán)完了’,并且還有該事件插入時的時間節(jié)點。

十六、console.markTimeline()
效果等同于console.timeStamp(),是console.timeStamp()以前的寫法,已經(jīng)淘汰了。
十七、console.timeLine('標(biāo)簽參數(shù)')配合 console.timeLineEnd('標(biāo)簽參數(shù)')
錄制一段時間的時間軸。
在Performance面板中,我們可以錄制當(dāng)前頁面的會話信息,而通過console.timeline和console.timelineEnd可以只錄制某一段時間的會話信息。
// 錄制第一段時間的會話信息
console.timeline('測試循環(huán)100萬相關(guān)的性能分析')
for (let i = 0; i < 1000000; i ++) {}
console.timelineEnd('測試循環(huán)100萬相關(guān)的性能分析')
// 錄制第二段時間的會話信息
console.timeline('測試循環(huán)1000萬相關(guān)的性能分析')
for (let i = 0; i < 10000000; i ++) {}
console.timelineEnd('測試循環(huán)1000萬相關(guān)的性能分析')
在我們的Performance面板中,點擊開始錄制當(dāng)前頁面,然后查看錄制后的結(jié)果:


console.timeline('參數(shù)標(biāo)簽')和console.timelineEnd('參數(shù)標(biāo)簽'),兩個方法需要接收相同的一個參數(shù)標(biāo)簽,就是一個標(biāo)識而已。
這里會了這個用法之后,更多的是怎樣在Performance中進行性能的分析,然后找出影響程序性能的瓶頸,這才是重要的。