此為轉(zhuǎn)載文章稿静,原文鏈接在底部~
我們在控制臺打印一下console寥闪,看看它還有哪些神奇的方法:
下面我們從最簡單的console.log方法開始恼五,逐個分析其他方法以及所涉及到的調(diào)試技巧。
一琐驴、console.log()打印內(nèi)容。
此處:主要聊一聊console.log()
的占位符秤标。其共有五種占位符
- %s 字符串
- %d 或 %i 整數(shù)
- %f 浮點數(shù)
- %o 對象的鏈接
- %c CSS格式字符串
如果方法的第一個參數(shù)中使用了占位符绝淡,那么就依次使用后面的參數(shù)進(jìn)行替換。
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ù)對前面的占位符進(jìn)行了替換衙猪,有點像我們字符串拼接的簡化操作茁帽。比如我們es5中的字符串拼接:
console.log('我叫' + name + ' ,' + age +'歲,有' + money + '元')
es6已經(jīng)有了更強(qiá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)一些刻诊。
補(bǔ)充修正:chrome并不是不支持console.debug防楷,只是默認(rèn)日志級別不打印調(diào)試信息,把verbose勾上就好了
三则涯、console.clear()
清除控制臺打印的內(nèi)容复局,并將光標(biāo)回歸到第一行
和我們點擊控制臺的這個清除按鈕的效果一樣
四、console.assert(表達(dá)式 [,arg1, arg2……argn])打印斷言
第一個參數(shù)是用來判斷是否打印斷言的表達(dá)式粟判,只有當(dāng)表達(dá)式的值為false的時候亿昏,才會打印后續(xù)的參數(shù):
const arr = [1, 2, 3];
// 打印斷言,如果arr[0]的值不等于2档礁,則打印提示信息
console.assert(arr[0] === 2, 'arr[0]的值不等于2');
- 客戶端的
console.assert()
打印斷言,并不會阻塞后續(xù)代碼的執(zhí)行呻澜,只是在斷言的表達(dá)式為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')
- 頁面中最多能同時運(yùn)行10,000個計時器
- 該方法并不會將結(jié)算結(jié)果返回到j(luò)s中,而只是能打印在控制臺上讨惩。所以不能使用此方法在js中來作為普通計時器使用或者進(jìn)行性能收集器的一部分辟癌。
七、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)容進(jìn)行分組
將打印的信息歸類分組打印砸紊,并且可以展開、折疊囱挑。
這在輸出大量數(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: ['擼碼', '計算機(jī)']
}
];
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選項贮尉,就可以將該選項添加到上面的紅框位置拌滋。然后點擊該面板,進(jìn)入對應(yīng)內(nèi)容:
然后我們點開每一個函數(shù)看下具體的情況:
- 1處猜谚,
Self Time
表示當(dāng)前函數(shù)自身運(yùn)行耗時败砂,什么意思赌渣?就是說當(dāng)前函數(shù)自身執(zhí)行耗時,不包括當(dāng)前函數(shù)中調(diào)用的其他函數(shù)運(yùn)行耗時昌犹。 - 2處坚芜,
Total Time
表示當(dāng)前函數(shù)運(yùn)行總耗時,包括了自身運(yùn)行耗時+函數(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ù)行最右邊還有會堆棧位置魁袜,點擊即可進(jìn)入
resouce
面板中該函數(shù)所在的文件位置桩撮。
如果你關(guān)注fun1函數(shù)的執(zhí)行時間,你可以點擊選中fun1這一行峰弹,然后點擊上面的眼睛圖標(biāo)店量,將自動只為你展現(xiàn)fun1函數(shù)的信息:
- 選中函數(shù)行,點擊眼睛即針對性的展示當(dāng)前函數(shù)鞠呈。
- 選中函數(shù)和融师,如果點擊×號,將會刪除當(dāng)前函數(shù)行蚁吝。
- 選中函數(shù)行點擊眼睛進(jìn)入后旱爆,如果想返回到上述全部函數(shù)行的面板,可以點擊上圖刷新按鈕窘茁』陈祝或者刪除了函數(shù)行后也可以恢復(fù)如上圖。
- 上圖三個按鈕只有在顏色變深的時候才可點擊山林,眼睛和×號只有在選中函數(shù)行的情況下可點房待,刷新按鈕在進(jìn)入或者刪除函數(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í)行的耗時次员。其他操作同上败许。
- 上部分藍(lán)色區(qū)域為cpu占用的大體走勢圖,可以清晰地看到每個時間節(jié)點的cpu占用情況淑蔚,是高是低一目了然市殷。
- 下半部分為每個函數(shù)開始運(yùn)行的時間節(jié)點。
如果點擊上部分藍(lán)色區(qū)域刹衫,還可以更細(xì)粒度查看當(dāng)前事件的函數(shù)運(yùn)行情況(在當(dāng)前時間節(jié)點劃分為更細(xì)的力度)醋寝,如下圖:
鼠標(biāo)移入某個函數(shù),還可以看到當(dāng)前函數(shù)所運(yùn)行的耗時情況带迟,如下圖:
console.profile() 和 console.profileEnd()函數(shù)性能分析器的建立音羞,給我們分析函數(shù)性能帶來的非常大的便利,這對于我們檢測程序運(yùn)行瓶頸非常有幫助仓犬。
十五嗅绰、console.timeStamp('事件信息')
在Performance(以前叫Timeline)性能面板中的會話錄制期間插入一條添加一個事件。
說到這個console.timeStamp()方法搀继,這個方法在我們進(jìn)行性能調(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中進(jìn)行性能的分析宣羊,然后找出影響程序性能的瓶頸璧诵,這才是重要的汰蜘。