轉載請注明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。
原文參考:https://www.sitepoint.com/beyond-console-log-level-up-your-debugging-skills/
在開發過程中,你可能會經常用到控制台命令console.log(),但是,其實除了這個命令外,還有一些其他的命令和技巧可供我們使用,讓我們看看它們究竟是什么,會不會為你的調試能力帶來一點新的啟發。
突破舒適區
同樣作為開發者,有一點不可否認的是程序員這個群體總是會不斷優化工作流程,使其變得更高效。不過這很容易使我們陷入誤區,讓我們很難突破已經慣有的工作流程,繼而閉耳塞聽得認為沒有比現在更好的工作方法和流程。
一般Web開發者的工作流程是在IDE中寫好代碼並保存,然后到瀏覽器中刷新測試。同時使用瀏覽器的DevTools調整CSS,還可以測試產品在不同分辨率和移動設備上的表現。在需要深入研究的地方可以通過添加 console.log()語句來調試我們的腳本。
如果console.log()在最終產品中被濫用,那么你在網上沖浪時如果一直打開DevTools,你就會在控制台中看到很多本不該出現在最終產品中的調試信息。
下面讓我為大家介紹一下除了console.log()之外的其他命令,看看它們會不會為各位的工作帶來什么新的啟發吧!
控制台的多種用法
我們可能已經習慣了通過 console.log("參數") 來了解程序中正在發生的事情,一般來說對於字符或數字這種類型的輸出,這種用法就足夠了,不過在輸出些類似像對象、數組類型的數據時卻沒有那么順手。
第一個技巧是在變量上加上大括號,這樣不僅可以打印出它們的值,還可以打印出變量的名稱,這使我們在日志中更方便的定位到什么值來自哪里。
let x = 2; console.log(x) // 2 console.log({x}) // {x: 2}
格式化日志
你可以在console.log中使用以百分號操作符指代不同格式的記錄值來格式化字符串,以下是操作符類型的定義:
- %s: 字符串
- %i或%d:整數。
- %f:浮點數。
- %c:CSS樣式。
- %o:可擴展DOM元素。
- %O:可擴展JavaScript對象。
你可以把它們分別放在控制台試試效果,首先是字符串和整數的示例:
console.log('%ix %s developer', 10, 'console'); // 10x console developer
如果計划將數字格式化為整型,可以使用如下示例:
console.log('%i', 12.34455241234324234); // 12
%c操作符可以令你使用CSS樣式定制輸出日志的樣式
console.log('%cPay attention to me','color:firebrick;font-size:40px')
其他更多日志功能可以查看官方文檔,看看有哪些已經實現了,避免重復造輪子。
分組日志
你可以使用console.group()來對日志進行分組,以將其顯示為可擴展和可折疊的組。
const label = 'The Millenium Falcon Crew'; console.group(label); console.log('Leia'); console.log('Han'); console.log('Chewie'); console.log('Ben'); console.groupEnd(label);
你可以嵌套分組,並可以使用 console.groupCollapsed() 在默認情況下不展開它們:
const extendedlabel = 'The Millenium Falcon Crew extended'; const meat = 'Humanoids'; const metal = 'Droids'; console.group(extendedlabel); console.groupCollapsed(meat); console.log('Leia'); console.log('Han'); console.log('Chewie'); console.log('Ben'); console.groupEnd(meat); console.group(metal); console.log('R2D2'); console.log('C3PO'); console.groupEnd(metal); console.groupEnd(extendedlabel);
日志控制台過濾
除了console.log外,你也可以使用 console.info()、console.error()和 console.warning()來代替它。通過這些語句,你可以在控制台側邊欄或下拉列表中來過濾你在控制台中看到的消息。這樣一來,你可以更容易地在來自第三方腳本和項目中的其他腳本中找到自己的日志消息。
其他控制台命令
你可能在debug時曾創建過統計某個方法被調用或被執行次數的變量。這里推薦另一種方法, console.count()和 console.countReset(),通過它們你可以創建任意數量的變量,並通過標簽來區分。
console.count('Chocula'); // Chocula: 1 console.count(); // default: 1 console.count('Chocula'); // Chocula: 2 console.countReset('Chocula'); console.count(); // default: 2 console.count(); // default: 3 console.count('Chocula'); // Chocula: 1
您還可以使用console.time()方法去統計代碼執行的總耗時:
console.time('go'); for(let i = 0; i < 200000; i+=1) { let x = Math.random()*2000; } console.timeEnd('go'); // go: 11.7861328125 ms
使用 console.dir()不僅可以顯示內容,還可以顯示你發送的數據類型。例如,如果你想要一個節點的XML表示,你可以使用console.dirxml()。而console.table()對於顯示JSON數據作為一個可排序的表格顯示效果也很好。
使用實時表達式Live Expression替代console.log
使用 console.log() 來監測那些變化范圍很大的數值時,不僅低效且困難。你可在在開發人員工具中通過點擊“眼睛“圖標來激活Live Expression功能。它可以將你想要關注的數值pin在工具頂端。
例如,你可以先輸入document.activeElement 來試試。該表達式表示當前獲得焦點的元素。
在這有一點需要說明,因為Live Expression並不和某一個站點及域名所關聯,所以它會一直保留在你的DevTools中。因此建議在完成一項調試后及時刪除它們,以免為調試其他站點時帶來不必要的麻煩。
使用控制台處理當前文檔
開發人員工具中的控制台不僅僅是用於顯示日志的一種方式。它是一個REPL,可讓您編寫和執行JavaScript並使用自動完成功能了解當前文檔的可用方法和屬性。
你可以試試,在開發人員工具的控制台,輸入doc
並按下tab,它會自動將其轉為document
。如果輸入’.’ 你會看到所有document可用的方法和屬性。這是一種學習可用方法和屬性的有趣且簡單的方法之一,這樣可以使你在短時間內寫出大量代碼。
除此之外,控制台和當前文檔進行交互還有很多快捷方式可供你使用 “控制台實用程序”。其中一些是:
- $_存儲最后一條控制台命令的結果。所以如果你之前輸入了2+2並按回車鍵,你在輸入$_將為你直接提供4。
- $0 到 $4 是你通過Elements 選項卡選中元素的堆棧,$0 為當前你選擇的元素。
- $() 通過選擇器選擇頁面中的元素
- $$()返回與給定選擇器匹配的元素數組。此命令等同於document.querySelectorAll()。。
- $x() 允許您通過XPATH選擇DOM元素。
- copy() 將您提供的所有內容復制到剪貼板。
- clear() 清除控制台。
- getEventListeners(node) 返回在指定對象上注冊的事件監聽器。
- monitorEvents(node, events) 監視並記錄對象上發生的事件。
- monitor(method) 每當調用方法時,都會創建一個日志。
其中有些方法的功能很強大,但可能我們在並不清楚的前提下自己實現了一系列 console.log() 語句。
例如如下使用場景:
monitorEvents(window, ['resize', 'scroll']); monitorEvents($0, 'key');
每次窗口滾動或調整大小時都會記錄一條日志。第二個示例比較有意思,因為它記錄了當前選定元素上的任何按鍵行為。
以下代碼列出頁面中的所有a標簽(因為$$('a')是document.querySelectorAll('a')的簡稱),並以可排序的表格形式顯示。作為table方法的第二個參數的數組定義了表格的列。否則,鏈接的每個屬性都會變成一列,那就很難瀏覽了。這個表不僅是可排序的,而且你還可以復制和粘貼它--例如,復制到Excel中。
console.table($$('a'),['href','text'])
與其使用復雜的JavaScript來過濾這些結果,你不如試試CSS選擇器。再比如,你想獲得一個文檔中所有非內嵌圖片的src和alt信息的表格,你可以使用以下方法:
console.table($$('img:not([src^=data])'), ['src','alt'])
另外,當您使用Markdown生成HTML時,大多數頁面生成器都會在標題上創建自動ID,例如 # New Stuff標題會變成<h1 id="new-stuff">New stuff</h1>。如果我需要批量創建許多指向這些錨點的URL,但不想手動去做這些事時,可能需要通過控制台編寫腳本來為我做這件事:
let out = ''; $$('#main [id]').filter( elm => {return elm.nodeName.startsWith('H')} ).forEach(elm => { out += `${elm.innerText} ${document.location.href}#${elm.id} ` }); copy(out);
結果是一個文本塊,每個標題的文本內容后跟指向該標題的完整URL。
這里展示了$$快捷方式的一個有趣的額外功能。document.querySelectorAll('#main [id]').filter() 會導致一個錯誤,因為返回的值不是一個數組而是一個NodeList。你需要用[...document.querySelectoAll('#main [id]').filter()]或Array.from(document.querySelectoAll('#main [id]').filter())方法把它強制轉換成一個Array,這在相當長的一段時間中困擾着從jQuery轉到JavaScript的開發者,而使用$$,可以直接使用所有的Array方法。
一般來說,你可以通過控制台來改變瀏覽器頁面中的所有元素。而且你還有一個額外的好處,就是可以使用DevTools的元素選項卡來獲得元素所有的頁面路徑。點擊每個元素旁的...菜單,並通過彈出的上下文菜單中選擇你要復制的路徑。
雖然控制台本身很好用,但很快你就會發現Console在編寫代碼存在着諸多困難,例如,Console是單行環境,不小心點擊Enter后就會立即執行。不過在這最后為大家介紹一個小技巧,你可以使用Shift + Enter來代替編寫多行腳本。
Sources
總的來說,Console是一個很好的測試環境,但對於編輯體驗來說卻很差。不過還好在Sources面板中也有一個完整的編輯器。在那里,你可以檢查當前頁面的代碼,並編寫更復雜的腳本與之交互。
除了點按上面tab菜單之外,DevTools還有一套快捷鍵Command Menu供你使用,你可以通過按control + shift + P(Windows, Linux)或Command+Shift+P(macOS)來訪問它。或選擇(...或⋮)菜單,選擇“Run command”。
Snippets 代碼片段
Snippets是保存你曾寫過的能明顯提高開發效率的代碼小片段。在DevTools中點擊Command Menu鍵盤快捷鍵,輸入snip並按下Enter鍵,選擇創建一個新的snippet,這樣就會進入Snippets編輯器,具體如下圖所示:
右邊的窗體包括一個完整的源碼編輯器,具有關鍵詞着色、自動補全、多光標等功能。下面我們開始試試上面的示例:
console.clear(); let out = ''; let problems = []; $$('a').forEach(a => { let text = a.innerText.trim(); let prefix = ''; if (!text) { if (a.querySelector('img')){ text = a.querySelector('img').alt; prefix = 'Image: '; } if (a.getAttribute('aria-label')) { text = a.getAttribute('aria-label'); prefix = 'Aria Label: '; } if (a.getAttribute('aria-labelledby')) { text = $('#' + a.getAttribute('aria-labelledby')).innerText; prefix = 'Aria Labelled By: '; } } if (text) { text = prefix + text } else { a.style.border = '1px solid firebrick'; problems.push(a); } out += ` ${text||'No Link text'} ${a.href}`; }); if (out === '') { console.warn('Sorry, no links found'); } else { copy(out); console.info('done harvesting links, ready to paste'); if (problems.length > 0) { console.warn('There were %d issues:', problems.length); console.groupCollapsed('Links without text'); problems.forEach(a => {console.dirxml(a)}); console.groupEnd('Links without text'); } }
以下是執行演示:
Overrides
Override是通過修改遠程文件的本地副本,實現本地測試替換服務器文件。例如,你可以在本地編輯完整的復雜樣式表,但無需等待冗長的重新build和部署過程即可看到效果,這也是能在開發階段即可發現問題的一種快捷的方式。
將開發人員工具和VS Code集成
你可以通過安裝Microsoft Edge Tools for VS Code擴展 ,即可在編輯中獲得開發人員工具,通過下圖可以看到基礎用法。
最后總結
希望通過這篇文章,可以使你能更全面的對DevTools有一些了解,而不僅僅只會使用console.log。另外作為一個開發人員除了上述的這些技巧外,還應多多習慣使用斷點及條件斷點進行調試,希望能夠通過更多的使用和練習來達到熟練的狀態。
拓展閱讀
如何在VScode中實現精准前端報表套打,一次性生成報表模板,批量打印。了解純前端在線報表控件,可以嵌入系統的在線報表開發工具。