靈活使用 console 讓 js 調試更簡單
摘要: 玩轉console。
- 原文:靈活使用 console 讓 js 調試更簡單
- 作者:前端小智
Fundebug經授權轉載,版權歸原作者所有。
Web 開發最常用的高度就是 console.log
,雖然 console.log
佔有一席之地,但很多人並沒有意識到 console
本身除了基本 log
方法之外還有很多其他方法。 適當使用這些方法可以使調試更容易,更快速,更直觀。
console.log()
在console.log
中有很多人們意想不到的功能。雖然大多數人使用 console.log(object)
來查看對象,但是你也可以使用 console.log(object, otherObject, string)
,它會把它們都整齊地記錄下來,偶爾也會很方便。
不僅如此,還有另一種格式化的: console.log(msg, values)
,這很像 C 或 PHP 中的sprintf
。
console.log("I like %s but I do not like %s.", "Skittles", "pus");
會像你預期的那樣輸出:
> I like Skittles but I do not like pus.
常見的佔位符 %o
(這是字母 o,不是 0),它接受對象,%s
接受字元串,%d
表示小數或整數。
另一個有趣的是 %c
,這可能與你所想不太相同,它實際上是 CSS 值的佔位符。使用%c 佔位符時,對應的後面的參數必須是 CSS 語句,用來對輸出內容進行 CSS 渲染。常見的輸出方式有兩種:文字樣式、圖片輸出
。
console.log(
"I am a %cbutton",
"color: white; background-color: orange; padding: 2px 5px; border-radius: 2px"
);
它並不優雅,也不是特別有用。當然,這並不是一個真正的按鈕。
它有用嗎? 恩恩恩。
console.dir()
在大多數情況下,console.dir()
的函數非常類似於 log()
,儘管它看起來略有不同。
下拉小箭頭將顯示與上面相同的對象詳細信息,這也可以從console.log
版本中看到。當你查看元素的結構時候,你會發現它們之間的差異更大,也更有趣。
let element = document.getElementById("2x-container");
使用 console.log
查看:
打開了一些元素,這清楚地顯示了 DOM,我們可以在其中導航。但是console.dir(element)
給出了更加方便查看 DOM 結構的輸出:
這是一種更客觀地看待元素的方式。有時候,這可能是您真正想要的,更像是檢查元素。
代碼部署後可能存在的 BUG 沒法實時知道,事後為瞭解決這些 BUG,花了大量的時間進行 log 調試,這邊順便給大家推薦一個好用的 BUG 監控工具 Fundebug。
console.warn()
可能是最明顯的直接替換 log()
,你可以以完全相同的方式使用 console.warn()
。 唯一真正的區別是輸出字的顏色是黃色的。 具體來說,輸出處於警告級別而不是信息級別,因此瀏覽器將稍微區別對待它。 這具有使其在雜亂輸出中更明顯的效果。
不過,還有一個更大的優勢,因為輸出是警告而不是信息,所以你可以過濾掉所有console.log
並僅保留console.warn
。 這對於偶爾會在瀏覽器中輸出大量無用廢話的應用程序尤其有用。 清除一些無用的信息可以讓你更輕鬆地看到你想要的輸出。
console.table()
令人驚訝的是,這並不是更為人所知,但是 console.table()
函數旨在以一種比僅僅轉出原始對象數組更整潔的方式顯示錶格數據。
例如,這裡有一個數據列表。
const data = [
{
id: "7cb1-e041b126-f3b8",
seller: "WAL0412",
buyer: "WAL3023",
price: 203450,
time: 1539688433
},
{
id: "1d4c-31f8f14b-1571",
seller: "WAL0452",
buyer: "WAL3023",
price: 348299,
time: 1539688433
},
{
id: "b12c-b3adf58f-809f",
seller: "WAL0012",
buyer: "WAL2025",
price: 59240,
time: 1539688433
}
];
如果我們使用 console.log
來輸出上面的內容,我們會得到一些非常無用的輸出:
? (3) [{…}, {…}, {…}]
點擊這個小箭頭可以展開看到對象的內容,但是,它並不是我們想要的「一目瞭然」。
但是 console.table(data)
的輸出要有用得多。
第二個可選參數是所需列的列表。顯然,所有列都是默認值,但我們也可以這樣做:
> console.table(data, ["id", "price"]);
這裡要注意的是這是亂序的 - 最右邊的列標題上的箭頭顯示了原因。 我點擊該列進行排序。 找到列的最大或最小,或者只是對數據進行不同的查看非常方便。 順便說一句,該功能與僅顯示一些列無關,它總是可用的。
console.table()
只能處理最多 1000 行,因此它可能不適合所有數據集。
console.assert()
assert()
與 log()
是相同的函數,assert()
是對輸入的表達式進行斷言,只有表達式為 false 時,才輸出相應的信息到控制檯,示例如下:
var arr = [1, 2, 3];
console.assert(arr.length === 4);
有時我們需要更複雜的條件句。例如,我們已經看到了用戶 WAL0412
的數據問題,並希望僅顯示來自這些數據的事務,這是直觀的解決方案。
console.assert(tx.buyer === "WAL0412", tx);
這看起來不錯,但行不通。記住,條件必須為false
,斷言才會執行,更改如下:
console.assert(tx.buyer !== "WAL0412", tx);
與其中一些類似,console.assert()
並不總是特別有用。但在特定的情況下,它可能是一個優雅的解決方案。
console.count()
另一個具有特殊用途的計數器,count 只是作為一個計數器,或者作為一個命名計數器,可以統計代碼被執行的次數。
for (let i = 0; i < 10000; i++) {
if (i % 2) {
console.count("odds");
}
if (!(i % 5)) {
console.count("multiplesOfFive");
}
if (isPrime(i)) {
console.count("prime");
}
}
這不是有用的代碼,而且有點抽象。這邊也不打算演示 isPrime
函數,假設它是成立的。
執行後我們會得到一個列表:
odds: 1
odds: 2
prime: 1
odds: 3
multiplesOfFive: 1
prime: 2
odds: 4
prime: 3
odds: 5
multiplesOfFive: 2
...
還有一個相關的 console.countReset()
,可以使用它重置計數器。
console.trace()
trace()
在簡單的數據中很難演示。當您試圖在類或庫中找出是哪個實際調用者導致了這個問題時,它的優勢就顯現出來了。
例如,可能有 12 個不同的組件調用一個服務,但是其中一個組件沒有正確地設置依賴項。
export default class CupcakeService {
?
constructor(dataLib) {
this.dataLib = dataLib;
if(typeof dataLib !== object) {
console.log(dataLib);
console.trace();
}
}
...
}
這裡使用 console.log()
僅告訴我們傳遞數據dataLib
是什麼 ,而沒有具體的傳遞的路徑。不過,console.trace()
會非常清楚地告訴我們問題出在 Dashboard.js
,我們可以看到是 new CupcakeService(false)
導致錯誤。
console.time()
console.time()
是一個用於跟蹤操作時間的專用函數,它是跟蹤 JavaScript 執行時間的好方法。
function slowFunction(number) {
var functionTimerStart = new Date().getTime();
// something slow or complex with the numbers.
// Factorials, or whatever.
var functionTime = new Date().getTime() - functionTimerStart;
console.log(`Function time: ${functionTime}`);
}
var start = new Date().getTime();
?
for (i = 0; i < 100000; ++i) {
slowFunction(i);
}
?
var time = new Date().getTime() - start;
console.log(`Execution time: ${time}`);
這是一種老派的做法,我們使用 console.time()
來簡化以上代碼。
const slowFunction = number => {
console.time("slowFunction");
// something slow or complex with the numbers.
// Factorials, or whatever.
console.timeEnd("slowFunction");
};
console.time();
?
for (i = 0; i < 100000; ++i) {
slowFunction(i);
}
console.timeEnd();
我們現在不再需要做任何計算或設置臨時變數。
console.group()
// this is the global scope
let number = 1;
console.group("OutsideLoop");
console.log(number);
console.group("Loop");
for (let i = 0; i < 5; i++) {
number = i + number;
console.log(number);
}
console.groupEnd();
console.log(number);
console.groupEnd();
console.log("All done now");
輸出如下:
並不是很有用,但是您可以看到其中一些是如何組合的。
class MyClass {
constructor(dataAccess) {
console.group("Constructor");
console.log("Constructor executed");
console.assert(
typeof dataAccess === "object",
"Potentially incorrect dataAccess object"
);
this.initializeEvents();
console.groupEnd();
}
initializeEvents() {
console.group("events");
console.log("Initialising events");
console.groupEnd();
}
}
let myClass = new MyClass(false);
這是很多工作和很多調試信息的代碼,可能不是那麼有用。 但它仍然是一個有趣的想法,這樣寫使你的日誌記錄更加清晰。
選擇 DOM 元素
如果熟悉 jQuery,就會知道 $(『.class』)
和 $(『#id』)
選擇器有多麼重要。它們根據與之關聯的類或 ID 選擇 DOM 元素。
但是當你沒有引用 jQuery 時,你仍然可以在谷歌開發控制檯中進行同樣的操作。
$(『tagName』) $(『.class』) $You cant use macro parameter character # in math mode(『#id』) and $(『.class #id』) 等效於document.querySelector(『 『)
,這將返回 DOM 中與選擇器匹配的第一個元素。
可以使用 $$(tagName)
或 $$(.class)
, 注意雙元符號,根據特定的選擇器選擇 DOM 的所有元素。這也將它們放入數組中,你也可以通過指定數組中該元素的位置來從中選擇特定的元素。
例如,$$(『.className』) 獲取具有類 className
的所有元素,而$$(『.className』)[0]
和 $$(『.className』)[1]
獲取到分別是第一個和第二個元素。
將瀏覽器轉換為編輯器
你有多少次想知道你是否可以在瀏覽器中編輯一些文本? 答案是肯定的,你可以將瀏覽器轉換為文本編輯器。 你可以在 DOM 中的任何位置添加文本和從中刪除文本。
你不再需要檢查元素並編輯 HTML。相反,進入開發人員控制檯並輸入以下內容:
document.body.contentEditable = true;
這將使內容可編輯。現在,你幾乎可以編輯 DOM 中的任何內容。
查找與 DOM 中的元素關聯的事件
調試時,需要查找 DOM 中某個元素的事件偵聽器感時,谷歌控制檯了 getEventListeners
使找到這些事件更加容易且直觀。
getEventListeners($(『selector』))
返回一個對象數組,其中包含綁定到該元素的所有事件。你可以展開對象來查看事件:
要找到特定事件的偵聽器,可以這樣做:
getEventListeners($(『selector』)).eventName[0].listener
這將顯示與特定事件關聯的偵聽器。這裡 eventName[0]
是一個數組,它列出了特定事件的所有事件。例如:
getEventListeners($(『firstName』)).click[0].listener
將顯示與 ID 為 『firstName』
的元素的單擊事件關聯的偵聽器。
監控事件
如果希望在執行綁定到 DOM 中特定元素的事件時監視它們,也可以在控制檯中這樣做。你可以使用不同的命令來監控其中的一些或所有事件:
如果希望在執行綁定到 DOM 中特定元素的事件時監視它們,也可以在控制檯中這樣做。你可以使用不同的命令來監控其中的一些或所有事件:
monitorEvents($(『selector』))
將監視與選擇器的元素關聯的所有事件,然後在它們被觸發時將它們列印到控制檯。例如,monitore($(#firstName))
將列印 ID 為firstName
元素的所有事件。monitorEvents($(『selector』),』eventName』)
將列印與元素綁定的特定事件。 你可以將事件名稱作為參數傳遞給函數。 這將僅記錄綁定到特定元素的特定事件。 例如,monitorEvents($(『#firstName』),』click』) 將列印綁定到 ID 為firstName的元素的所有click
事件。monitore($(selector),[eventName1, eventName3, .])
將根據您自己的需求記錄多個事件。與其傳遞單個事件名作為參數,不如傳遞包含所有事件的字元串數組。例如monitore($(#firstName),[click, focus])
將記錄與 ID firstName 元素綁定的click
事件和focus
事件。unmonitorevent ($(selector))
:這將停止監視和列印控制檯中的事件。
檢查 DOM 中的一個元素
你可以直接從控制檯檢查一個元素:
- inspect($將檢查與選擇器匹配的元素,並轉到中的選項卡。例如,(『selector』)) 將檢查與選擇器匹配的元素,並轉到 Chrome Developer Tools 中的 **Elements** 選項卡。 例如,
inspect($(『#firstName』))
將檢查 ID 為firstName 的元素,spect($(『a』)[3])
將檢查 DOM 中的第 4 個a
元素。 - $0, $1, $等可以幫助你獲取最近檢查過的元素。例如,2 等可以幫助你獲取最近檢查過的元素。 例如,
$0
表示最後檢查的 DOM 元素,而$1
倒數第二個檢查的 DOM 元素。
檢索最後一個結果的值
你可以將控制檯用作計算器。當你這樣做的時候,你可能需要用第二個來跟蹤一個計算。以下是如何從內存中檢索先前計算的結果:
$_;
過程如下:
2 + 3 + 4;
9; //- The Answer of the SUM is 9
?
$_;
9; // Gives the last Result
?
$_ * $_;
81; // As the last Result was 9
?
Math.sqrt($_);
9; // As the last Result was 81
?
$_;
9; // As the Last Result is 9
清除控制檯和內存
如果你想清除控制檯及其內存,輸入如下:
clear();
原文:
- Beyond console.log()
- Things you probably didn』t know you could do with Chrome』s Developer Console
關於Fundebug
Fundebug專註於JavaScript、微信小程序、微信小遊戲、支付寶小程序、React Native、Node.js和Java線上應用實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了10億+錯誤事件,付費客戶有Google、360、金山軟體、百姓網等眾多品牌企業。歡迎大家免費試用!
推薦閱讀: