你需要知道的 19 個 console 實用調試技巧!
大家好,我是 CUGGZ。
瀏覽器的開發者工具爲我們提供了強大的調試系統,可以用來查看 DOM 樹結構、CSS 樣式調試、動畫調試、JavaScript 代碼斷點調試等。今天我們就來看看 console 調試的那些實用的調試技巧。
如今,我們項目的開發通常會使用 React、Vue 等前端框架,前端調試也變得更加有難度,除了使用 React DevTools,Vue DevTools 等插件之外,我們使用最多的就是 console.log() 了,當然多數情況下,console.log() 就能滿足我們的需求,但是當數據變得比較複雜時,console.log() 就顯得有些單一。其實 console 對象提供了很多方法,下面是 console 對象包含的方法:
console 對象提供了瀏覽器控制檯調試的接口,我們可以從任何全局對象中訪問到它,如果你平時只是用 console.log() 來輸出一些變量,那你可能沒有用過 console 那些強大的功能。下面帶你用 console 玩玩花式調試。
一、基本打印
1. console.log()
console.log() 就是最基本、最常用的用法了。它可以用在 JavaScript 代碼的任何地方,然後就可以瀏覽器的控制檯中看到打印的信息。其基本使用方法如下:
let name = "CUGGZ";
let age = 18;
console.log(name) // CUGGZ
console.log(name, age) // CUGGZ 18
console.log("message:", name, age) // message: CUGGZ 18
除此之外,console.log() 還支持下面這種輸出方式:
let name = "CUGGZ";
let age = 18;
let height = 180;
console.log('Name: %s, Age: %d', name, age) // Name: CUGGZ, Age: 18
console.log('Age: %d, Height: %d', age, height) // Age: 18, Height: 180
這裏將後面的變量賦值給了前面的佔位符的位置,他們是一一對應的。這種寫法在複雜的輸出時,能保證模板和數據分離,結構更加清晰。不過如果是簡單的輸出,就沒必要這樣寫了。在 console.log 中,支持的佔位符格式如下:
-
字符串:%s
-
整數:%d
-
浮點數:%f
-
對象:%o 或 %O
-
CSS 樣式:%c
可以看到,除了最基本的幾種類型之外,它還支持定義 CSS 樣式:
let name = "CUGGZ";
console.log('My Name is %cCUGGZ', 'color: skyblue; font-size: 30px;')
打印結果如下(好像並沒有什麼卵用):
這個樣式打印可能有用的地方就是打印圖片,用來查看圖片是否正確:
console.log('%c ','background-image:url("http://iyeslogo.orbrand.com/150902Google/005.gif");background-size:120% 120%;background-repeat:no-repeat;background-position:center center;line-height:60px;padding:30px 120px;');
打印結果如下:
嚴格地說,console.log() 並不支持打印圖片,但是可以使用 CSS 的背景圖來打印圖片,不過並不能直接打印,因爲是不支持設置圖片的寬高屬性,所以就需要使用 line-heigh 和 padding 來撐開圖片,使其可以正常顯示出來。
我們可以使用 console.log() 來打印字符畫,就像知乎的這樣:
可以使用字符畫在線生成工具,將生成的字符粘貼到 console.log() 即可。在線工具:mg2txt。我的頭像生成效果如下,中間的就是生成的字符:
除此之外,可以看到,當佔位符表示一個對象時,有兩種寫法:%c 或者 %C,那它們兩個有什麼區別呢?當我們指定的對象是普通的 object 對象時,它們兩個是沒有區別的,如果是 DOM 節點,那就有有區別了,來看下面的示例:
可以看到,使用 %o 打印的是 DOM 節點的內容,包含其子節點。而 %O 打印的是該 DOM 節點的對象屬性,可以根據需求來選擇性的打印。
2. console.warn()
console.warn() 方法用於在控制檯輸出警告信息。它的用法和 console.log 是完全一樣的,只是顯示的樣式不太一樣,信息最前面加一個黃色三角,表示警告:
const app = ["facebook", "google", "twitter"];
console.warn(app);
打印樣式如下:
3. console.error()
console.error() 可以用於在控制檯輸出錯誤信息。它和上面的兩個方法的用法是一樣的,只是顯示樣式不一樣:
const app = ["facebook", "google", "twitter"];
console.error(app);
需要注意,console.exception() 是 console.error() 的別名,它們功能是相同的。
當然,console.error() 還有一個 console.log() 不具備的功能,那就是打印函數的調用棧:
function a() {
b();
}
function b() {
console.error("error");
}
function c() {
a();
}
c();
打印結果如下:
可以看到,這裏打印出來了函數函數調用棧的信息:b→a→c。
console 對象提供了專門的方法來打印函數的調用棧(console.trace()),這個下面會介紹到。
4. console.info()
console.info() 可以用來打印資訊類說明信息,它和 console.log() 的用法一致,打印出來的效果也是一樣的:
二、打印時間
1. console.time() & console.timeEnd()
如果我們想要獲取一段代碼的執行時間,就可以使用 console 對象的 console.time() 和 console.timeEnd() 方法,來看下面的例子:
console.time();
setTimeout(() => {
console.timeEnd();
}, 1000);
// default: 1001.9140625 ms
它們都可以傳遞一個參數,該參數是一個字符串,用來標記唯一的計時器。如果頁面只有一個計時器時,就不需要傳這個參數 ,如果有多個計時器,就需要使用這個標籤來標記每一個計時器:
console.time("timer1");
console.time("timer2");
setTimeout(() => {
console.timeEnd("timer1");
}, 1000);
setTimeout(() => {
console.timeEnd("timer2");
}, 2000);
// timer1: 1004.666259765625 ms
// timer2: 2004.654052734375 ms
2. console.timeLog()
這裏的 console.timeLog() 上面的 console.timeEnd() 類似,但是也有一定的差別。他們都需要使用 console.time() 來啓動一個計時器。然後 console.timeLog() 就是打印計時器當前的時間,而 console.timeEnd() 是打印計時器,直到結束的時間。下面來看例子:
console.time("timer");
setTimeout(() => {
console.timeLog("timer")
setTimeout(() => {
console.timeLog("timer");
}, 2000);
}, 1000);
// timer: 1002.80224609375 ms
// timer: 3008.044189453125 ms
而使用 console.timeEnd() 時:
console.time("timer");
setTimeout(() => {
console.timeEnd("timer")
setTimeout(() => {
console.timeLog("timer");
}, 2000);
}, 1000);
打印結果如下:
可以看到,它會終止當前的計時器,所以裏面的 timeLog 就無法在找到 timer 計數器了。所以兩者的區別就在於,是否會終止當前的計時。
三、分組打印
1. console.group() & console.groupEnd()
這兩個方法用於在控制檯創建一個信息分組。一個完整的信息分組以 console.group() 開始,console.groupEnd() 結束。來看下面的例子:
console.group();
console.log('First Group');
console.group();
console.log('Second Group')
console.groupEnd();
console.groupEnd();
打印結果如下:
再來看一個複雜點的:
console.group("Alphabet")
console.log("A");
console.log("B");
console.log("C");
console.group("Numbers");
console.log("One");
console.log("Two");
console.groupEnd("Numbers");
console.groupEnd("Alphabet");
打印結果如下:
可以看到,這些分組是可以嵌套的。當前我們需要調試一大堆調試輸出,就可以選擇使用分組輸出,
2. console.groupCollapsed()
console.groupCollapsed() 方法類似於 console.group(),它們都需要使用 console.groupEnd() 來結束分組。不同的是,該方法默認打印的信息是摺疊展示的,而 group() 是默認展開的。來對上面的例子進行改寫:
console.groupCollapsed("Alphabet")
console.log("A");
console.log("B");
console.log("C");
console.groupCollapsed("Numbers");
console.log("One");
console.log("Two");
console.groupEnd("Numbers");
console.groupEnd("Alphabet");
其打印結果如下:
可以看到,和上面方法唯一的不同就是,打印的結果被摺疊了,需要手動展開來看。
四、打印計次
1. console.count()
可以使用使用 console.count() 來獲取當前執行的次數。來看下面的例子:
for (i = 0; i < 5; i++) {
console.count();
}
// 輸出結果如下
default: 1
default: 2
default: 3
default: 4
default: 5
它也可以傳一個參數來進行標記(如果爲空,則爲默認標籤 default):
for (i = 0; i < 5; i++) {
console.count("hello");
}
// 輸出結果如下
hello: 1
hello: 2
hello: 3
hello: 4
hello: 5
這個方法主要用於一些比較複雜的場景,有時候一個函數被多個地方調用,就可以使用這個方法來確定是否少調用或者重複調用了該方法。
2. console.countReset()
顧名思義,console.countReset() 就是重置計算器,它會需要配合上面的 console.count() 方法使用。它有一個可選的參數 label:
-
如果提供了參數 label,此函數會重置與 label 關聯的計數,將 count 重置爲 0。
-
如果省略了參數 label,此函數會重置默認的計數器,將 count 重置爲 0。
console.count();
console.count("a");
console.count("b");
console.count("a");
console.count("a");
console.count();
console.count();
console.countReset();
console.countReset("a");
console.countReset("b");
console.count();
console.count("a");
console.count("b");
打印結果如下:
default:1
a:1
b:1
a:2
a:3
default:2
default:3
default:1
a:1
b:1
五、其他打印
1. console.table()
我們平時使用 console.log 較多,其實 console 對象還有很多屬性可以使用,比如 console.table(),使用它可以方便的打印數組對象的屬性,打印結果是一個表格。console.table() 方法有兩個參數,第一個參數是需要打印的對象,第二個參數是需要打印的表格的標題,這裏就是數組對象的屬性值。來看下面的例子:
const users = [
{
"first_name":"Harcourt",
"last_name":"Huckerbe",
"gender":"Male",
"city":"Linchen",
"birth_country":"China"
},
{
"first_name":"Allyn",
"last_name":"McEttigen",
"gender":"Male",
"city":"Ambelókipoi",
"birth_country":"Greece"
},
{
"first_name":"Sandor",
"last_name":"Degg",
"gender":"Male",
"city":"Mthatha",
"birth_country":"South Africa"
}
]
console.table(users, ['first_name', 'last_name', 'city']);
打印結果如下:
通過這種方式,可以更加清晰的看到數組對象中的指定屬性。
除此之外,還可以使用 console.table() 來打印數組元素:
const app = ["facebook", "google", "twitter"];
console.table(app);
打印結果如下:
需要注意,console.table() 只能處理最多 1000 行,因此它可能不適合所有數據集。但是也能適用於多數場景了。
2. console.clear()
console.clear() 顧名思義就是清除控制檯的信息。當清空控制檯之後,會打印一句:“Console was clered”:
當然,我們完全可以使用控制檯的清除鍵清除控制檯:
3. console.assert()
console.assert() 方法用於語句斷言,當斷言爲 false 時,則在信息到控制檯輸出錯誤信息。它的語法如下:
console.assert(expression, message)
它有兩個參數:
-
expression: 條件語句,語句會被解析成 Boolean,且爲 false 的時候會觸發 message 語句輸出;
-
message: 輸出語句,可以是任意類型。
該方法會在 expression 條件語句爲 false 時,就會打印 message 信息。當在特定情況下才輸出語句時,就可以使用 console.assert() 方法。
比如,當列表元素的子節點數量大於等於 100 時,打印錯誤信息:
console.assert(list.childNodes.length < 100, "Node count is > 100");
其輸出結果如下圖所示:
4. console.trace()
console.trace() 方法可以用於打印當前執行的代碼在堆棧中的調用路徑。它和上面的 console.error() 的功一致,不過打印的樣式就和 console.log() 是一樣的了。來看下面的例子:
function a() {
b();
}
function b() {
console.trace();
}
function c() {
a();
}
c();
打印結果如下:
可以看到,這裏輸出了調用棧的信息:b→a→c,這個堆棧信息是從調用位置開始的。
5. console.dir()
console.dir() 方法可以在控制檯中顯示指定 JavaScript 對象的屬性,並通過類似文件樹樣式的交互列表顯示。它的語法如下:
console.dir(object);
它的參數是一個對象,最終會打印出該對象所有的屬性和屬性值。
在多數情況下,使用 consoledir() 和使用 console.log() 的效果是一樣的。但是當打印元素結構時,就會有很大的差異了,console.log() 打印的是元素的 DOM 結構,而 console.dir() 打印的是元素的屬性:
6. console.dirxml()
console.dirxml() 方法用於顯示一個明確的 XML/HTML 元素的包括所有後代元素的交互樹。如果無法作爲一個 element 被顯示,那麼會以 JavaScript 對象的形式作爲替代。它的輸出是一個繼承的擴展的節點列表,可以讓你看到子節點的內容。其語法如下:
console.dirxml(object);
該方法會打印輸出 XML 元素及其後代元素,對於 XML 和 HTML 元素調用 console.log() 和 console.dirxml() 是等價的。
7. console.memory
console.memory 是 console 對象的一個屬性,而不是一個方法。它可以用來查看當前內存的使用情況,如果使用過多的 console.log() 會佔用較多的內存,導致瀏覽器出現卡頓情況。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/MEg0MsIPbnSa5u6e6yOn7Q