今天再來聊聊另一個重要的工具,是很多人剛開始學 Javascript 就一路接觸到現在,如果沒有這個工具,大家的工時可能至少要拉長一個小時(?)
我們來聊聊很熟卻不是那麼熟的 - 開發人員工具!
我想。。。這個主題大家都熟到不能再熟了,所以我直接挑幾個自己常用的工具,跟大家分享:
可以直接操作 DOM 元素的 style,而且立馬看到操作後的結果,確定正確之後再把修改貼回編輯器,對於需要調整版面、美觀、對齊等,都是大幅提升效率的做法:
好啦 console.log
大家都比鄰居還熟了,是個充滿安心感的語法,只要它登場,問題通常很快可以解決,然後我們要記得砍了它XD
這邊只是強調一個不太直覺的小重點,往往會讓新手感到困惑,下面這段範例:
const person = {
name: 'Joey',
salary: 30000
};
console.log(person);
person.salary += 1000;
console.log(person);
看起來滿正常的,當它印出來的時候:
但是當你想要展開這個物件,看更詳細的時候:
老師!我抓到瀏覽器的 bug 了!我是不是可以去 Google 工作了!?
先不要急著投履歷,雖然第一個 console 感覺應該要顯示 30000,但讓我們先來看看它後面那個藍色的 i 提示,把滑鼠移上去會顯示:
This value was evaluated upon first expanding. It may have changed since then.
簡單來說,它會在你第一次將這個物件展開的那一刻,才去取得這個物件目前的值。
而這一點是針對那些 non-primitive 的物件們,所以 Array
、Object
、Date
之類的物件都會有類似的狀況;反之,string
、number
、boolean
就不會,畢竟也沒有地方讓你展開就是了。
知道這點後就能了解,是因為程式已經執行完(salary
變成 31000
),我們才用滑鼠展開物件,因此在點擊下去的那一刻,物件已經是更新後的狀態了!
要嘛,你很確定這個物件從 console.log
的那一行,到程式結束,到被你的滑鼠點開,這段過程都沒有修改過物件,那就可以用。
要嘛,只取你真正想看的 property 來印,比如這樣:
const person = {
name: 'Joey',
salary: 30000
};
console.log(person.salary);
person.salary += 1000;
console.log(person.salary);
執行結果
30000
31000
console.log
的那一刻:const person = {
name: 'Joey',
salary: 30000
};
console.log(JSON.parse(JSON.stringify(person)));
person.salary += 1000;
console.log(JSON.parse(JSON.stringify(person)));
執行結果
這個方法是從 MDN 來的,顯然,這個方法幾乎 100% 可以達成目的,但不僅不好閱讀,記得我們在 Day 4 討論過的,背後付出的效能也相當龐大,所以盡量用上面兩種方法吧!
這點就見仁見智,通常我要印多個 log,尤其還加上迴圈的時候,偶爾會忘記到底哪個是哪個,比如我想要計算商品打折後的價錢,並且跟原價放在一起對比:
const arr = [
{ name: 'laptop', price: 30000, discount: 0.7 },
{ name: 'TV', price: 12000, discount: 0.8 },
{ name: 'washing machine', price: 8000, discount: 0.85 },
];
arr.forEach(item => {
console.log(item.price);
console.log(item.price * item.discount);
});
執行結果
30000
21000
12000
9600
8000
6800
痾。。。所以 9600
到底是誰的價錢?是打折後的嗎?
另外還有在後端環境(比如 Node js) 要 log,往往會有很多其他的 log (比如 api call log) 混雜其中,這時候要找你的剛寫的 log 也是一大挑戰。
這邊比較難 demo 出那種感覺,但我相信,如果你有在 log 視窗滾動滑鼠超過 3 秒,還是找不到自己的 log,那應該就知道我在說什麼!
Log 畢竟是給自己看的,所以不要客氣,詳細一點、租暴顯眼一點:
const arr = [
{ name: 'laptop', price: 30000, discount: 0.7 },
{ name: 'TV', price: 12000, discount: 0.8 },
{ name: 'washing machine', price: 8000, discount: 0.85 },
];
arr.forEach((item, index) => {
console.log(`====== ${index} ======`);
console.log('name', item.name);
console.log('price', item.price);
console.log('discountedPrice', item.price * item.discount);
});
執行結果
====== 0 ======
name laptop
price 30000
discountedPrice 21000
====== 1 ======
name TV
price 12000
discountedPrice 9600
====== 2 ======
name washing machine
price 8000
discountedPrice 6800
啊我把 log 打那麼詳細的時間,直接拿來找 log 還比較快!
當然啦,對於很簡單的 bug 的確不用這麼費力,但是當程式反覆修改都找不到 bug 時,一段美麗的 console.log
才能夠讓你保持不至於崩壞的心情((逃
這個大部分人都了解的,可以直接把上面任何一段 code 複製貼到 console 裡面執行,它內部就有個 Javascript 引擎可以執行。
我經常在忘記 substr
與 substring
的差別,或者 regex
跑出來到底是不是我要的,這時候就可以寫個很簡單的測試程式上去,立馬得到結果:
console.log('apple'.substr(1, 3));
console.log('apple'.substring(1, 3));
執行結果
ppl
pp
相較於 console.log
把過程中的變數印出來,使用中斷點則更厲害了,可以做到把網頁畫面一格一格呈現的效果!
比如一個會印出平方表到畫面上的程式:
let html = "";
for (let i = 1; i <= 5; i++) {
html += "<span>" + i + "的平方是" + (i * i) + "</span>";
document.querySelector("#center").innerHTML = html;
}
每次重新整理都是唰一聲就五筆都跑出來,如果想要看「分解動作」,可以在迴圈結束的時候,放上一個 debugger
:
let html = "";
for (let i = 1; i <= 5; i++) {
html += `<span>${i}的平方是${(i * i)}</span>`;
document.querySelector("#center").innerHTML = html;
debugger;
}
然後在打開開發人員工具的情況下,重新整理:
透過中斷點,除了可以看到網頁上的定格行進,還可以看到元素是在哪一行 code 執行後才跑出來的。
如果說 console.log
可以用來抓「資料方面的 bug」,那 break point 應該滿適合用來抓「畫面方面的 bug」。
如果前後端不是透過 SSR 的方式將畫面送到前端,通常就會將資料透過 http request 送到前端,這時就不一定要透過 console.log
去把資料印出來,可以直接到 Network 頁籤看看,從後端傳了什麼東西來!
這就比較不是實用的部分了啦XD,如果對方的網站程式碼沒有特別 uglify 處理,就能夠直接看到一些畫面或資料操作的 code:
爬蟲的部分,或許也會在 Network 頁籤找到一絲蛛絲馬跡唷!
筆者還真的有某個元件互動行為寫不出來,跑去看在線上的網頁怎麼寫的XD
這個章節還滿有趣的,今天開發人員工具大概只講了冰山一角,還有非常廣大的世界等著探索!
不過起碼以我個人,真的日常每天在用的,大概就是上述那些,大家不妨分享自己還有什麼很不錯的工具用法!
每日的修練
塑成信手拈來的熟練
這時候只能推這個冠軍 你所不知道的各種前端 Debug 技巧 系列文了 (也有書可以看囉)
讚啦!這我之前有追,非常適合更深入的 debug 技巧學習!