身為一個開發者,當然都會了解經驗越多,除錯上會更為容易,這種事情你我都清楚。但對於一個新手來就是缺少錯誤上的經驗,所以當遇到紅字時會不知如何著手。
這一系列的文章是專門給剛入門新手的前端開發者觀看的,盡可能用白話的方式,並且提供簡單的範例程式碼以供驗證。
Chrome 開發者工具的 Console 相當好用,最常使用的不外乎是透過console.log
呈現出變數或運算的結果,如果符合預期則皆大歡喜。
但最討厭的則是出現紅色文字,看似帶有威脅的語氣說「你出錯了!」,對於新手來說不僅是一種挫折,紅字上的錯誤也不知如何著手排除的情況下,也只能反覆地檢視自己原始碼,看看是不是有奇怪的地方,但就算停在了錯誤地方也往往不知是什麼意思,也會因此花上許多時間在除錯上。
本篇就來介紹 Chrome 開發者工具的常見錯誤回饋及排除技巧,讓你下次不再需要為了滿滿的紅字感到挫折,更能從中學習如何快速搜尋錯誤程式碼。
注意:JavaScript 是屬於同步的程式語言,如果出現錯誤就會造成下方的程式碼導致無法運行,當紅字沒有解決,都可能造成接下來的程式碼運行錯誤或是無法繼續運行。
SyntaxError
這類型錯誤通常是語法結構錯誤,遇到這類型錯誤建議透過 “文字編輯器”除錯,以 VSCode 來說會直接跳出這類型的錯誤提示。
如下圖,VSCode 以紅字提示 family 物件有錯誤,當出現錯誤時會建議不要只檢查當行,錯誤可能會存在於前後文之中(有可能跨多行的錯誤),此範例中仔細檢查可以發現 '小明' 後方缺少了一個逗點。
除錯重點:使用主流的文字編輯器,如 "VSCode" 進行除錯
var person = {
name: '小明'
family: {
name: '小明家'
}
}
語法解析錯誤,因為在物件結構中缺少一個逗點,除了透過 VSCode 查看外,也可以直接透過 Chrome Console 連結至 Source 頁面查看錯誤行數,並請檢查此行的前後文是否有語法結構上的錯誤。
function fn() {
console.log('這是一段函式');
console.log(fn);
語法解析錯誤:未預期的結束,此範例中缺少結尾的 }
,會建議在撰寫程式碼時盡可能維持正確的縮排,將程式排整齊後比較容易正確找到錯誤。
if (name)
console.log('立即函式')
};
語法解析錯誤:未預期的符號 }
,程式碼多了 }
結尾符號導致環境運行錯誤,此錯誤排除與上述相同,盡可能將程式碼排整齊且維持首尾符號的一致。
除此之外再推薦一個 VSCode 工具,為你的首尾標籤加上對應的色彩:https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer
範例:程式碼中的 {}
都會以一對的色彩呈現。
let a;
let a;
語法解析錯誤:識別符號(在此指的是變數)已經被宣告,請避免重複宣告同一個變數,ES6 中都禁止 let、const 重複宣告,直接排除即可。
ReferenceError
此類型錯誤通常是指「參考」找不到,當出現這類型錯誤時文字編輯器 “不一定” 出現錯誤(有裝 Linter 才會提示),所以時常會在執行階段才會看到這類型錯誤。
除錯重點:
- 透過 Chrome 的提示修正
- 在 JavaScript 撰寫環境中安裝 ESLint
ReferenceError: a is not defined
語法參考錯誤:由於 a 變數未定義,所以在取用該變數時會出現未定義的提示,只要預先定義此變數即可。
不過還有另一種很常見的情況,當引用外部套件時出現「套件名稱 + is not defined
」,這類型情況通常是外部資源沒有正確載入,請確保該資源有加入到此網站中。
以下範例來說,就是屬於 jQuery 沒有正確導入。
Uncaught ReferenceError: $ is not defined
TypeError
則是型別上的錯誤,文字編輯器一樣不會預先提示有錯,必須在執行環境時才會看到,這類型的錯誤通常是以下幾種:
'text'()
)除錯重點:在取得變數前方確認該變數當前的資料型別及結構
var a;
console.log(a.a);
說明:該變數的值下無法找到特定的屬性,undefined、null 的值內無法在查找到其它的屬性,如果無法確認該變數是否為 undefined
,可改寫其程式碼如下:
if (typeof a !== 'undefined') {
console.log(a.a);
}
console.log('a')
(function() {
console.log('立即函式')
})()
說明:這段程式碼中看起來會是立即函式的錯誤,但卻出現了 console.log(...) is not a function
。此錯誤主要是因為缺少了分號,因此將兩段程式碼合併為一行執行,運行的結果如下:
console.log('a')(function() { ... })()
當遇到此類型錯誤只要在兩者之間補上分號即可正常運作。
console.log('a');
(function() {
console.log('立即函式')
})()
這是建立了超過長度的陣列或過度的執行函式(產生過多執行堆疊)所造成的錯誤,這類型則需要重新檢視程式碼的邏輯,是否會造成過度的硬體資源消耗(記憶體或運算資源)。
除錯重點:需重新檢視邏輯,如果必要可先刪除部分程式碼,先找出錯誤的片段後再進行除錯。
(function a() {
a();
})();
說明:函式呼叫時會產生一個執行堆疊,如果堆疊的過程中超過最大數量則會產生錯誤(函式內呼叫自己)。
此類錯誤也很常見,但卻不容易找到為何出錯,主要原因是執行堆疊超過環境的限制(運用框架中也很常見),如果遇到此錯誤建議改寫目前呼叫函式的方式。
當 Chrome Console 出現錯誤時請維持正確的心態,新手常常會看到錯誤而緊張不知所措(畢竟從小紅被用紅字提醒就會感到緊張,深怕這個錯誤自己無法解決而影響到其他人)。
錯誤在撰寫程式碼中常見的過程,資深開發者與新手的差異是面對錯誤的經驗,同一個錯誤前幾次不清楚沒關係,都是經驗的累積,只要往後再次遇到相同的錯誤自然而然就能輕鬆面對。