iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 1
1
Modern Web

前端常見問題攻略系列 第 1

JavaScript 開發中常見錯誤解決辦法

身為一個開發者,當然都會了解經驗越多,除錯上會更為容易,這種事情你我都清楚。但對於一個新手來就是缺少錯誤上的經驗,所以當遇到紅字時會不知如何著手。

這一系列的文章是專門給剛入門新手的前端開發者觀看的,盡可能用白話的方式,並且提供簡單的範例程式碼以供驗證。

Chrome 開發者工具的常見錯誤排解

Chrome 開發者工具的 Console 相當好用,最常使用的不外乎是透過console.log 呈現出變數或運算的結果,如果符合預期則皆大歡喜。

但最討厭的則是出現紅色文字,看似帶有威脅的語氣說「你出錯了!」,對於新手來說不僅是一種挫折,紅字上的錯誤也不知如何著手排除的情況下,也只能反覆地檢視自己原始碼,看看是不是有奇怪的地方,但就算停在了錯誤地方也往往不知是什麼意思,也會因此花上許多時間在除錯上。

本篇就來介紹 Chrome 開發者工具的常見錯誤回饋及排除技巧,讓你下次不再需要為了滿滿的紅字感到挫折,更能從中學習如何快速搜尋錯誤程式碼。

注意:JavaScript 是屬於同步的程式語言,如果出現錯誤就會造成下方的程式碼導致無法運行,當紅字沒有解決,都可能造成接下來的程式碼運行錯誤或是無法繼續運行

錯誤類型:SyntaxError

SyntaxError 這類型錯誤通常是語法結構錯誤,遇到這類型錯誤建議透過 “文字編輯器”除錯,以 VSCode 來說會直接跳出這類型的錯誤提示。

如下圖,VSCode 以紅字提示 family 物件有錯誤,當出現錯誤時會建議不要只檢查當行,錯誤可能會存在於前後文之中(有可能跨多行的錯誤),此範例中仔細檢查可以發現 '小明' 後方缺少了一個逗點。

https://ithelp.ithome.com.tw/upload/images/20200916/200836088qDnYU2JL4.png

除錯重點:使用主流的文字編輯器,如 "VSCode" 進行除錯

Uncaught SyntaxError: Unexpected identifier

var person = {
  name: '小明'
  family: {
    name: '小明家'
  }
}

https://ithelp.ithome.com.tw/upload/images/20200916/20083608nQP9KwCRug.png

語法解析錯誤,因為在物件結構中缺少一個逗點,除了透過 VSCode 查看外,也可以直接透過 Chrome Console 連結至 Source 頁面查看錯誤行數,並請檢查此行的前後文是否有語法結構上的錯誤。

https://ithelp.ithome.com.tw/upload/images/20200916/200836088svPA9r72P.png

Uncaught SyntaxError: Unexpected end of input

function fn() {
  console.log('這是一段函式');
console.log(fn);

語法解析錯誤:未預期的結束,此範例中缺少結尾的 },會建議在撰寫程式碼時盡可能維持正確的縮排,將程式排整齊後比較容易正確找到錯誤。

https://ithelp.ithome.com.tw/upload/images/20200916/20083608RvswZ1LhVl.png

Uncaught SyntaxError: Unexpected token '}'

if (name)
  console.log('立即函式')
};

https://ithelp.ithome.com.tw/upload/images/20200916/20083608DZFilBwUrC.png

語法解析錯誤:未預期的符號 },程式碼多了 } 結尾符號導致環境運行錯誤,此錯誤排除與上述相同,盡可能將程式碼排整齊且維持首尾符號的一致。

除此之外再推薦一個 VSCode 工具,為你的首尾標籤加上對應的色彩:https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer

範例:程式碼中的 {} 都會以一對的色彩呈現。
https://ithelp.ithome.com.tw/upload/images/20200916/20083608EGZ7ywvf99.png

Uncaught SyntaxError: Identifier 'a' has already been declared

let a;
let a;

語法解析錯誤:識別符號(在此指的是變數)已經被宣告,請避免重複宣告同一個變數,ES6 中都禁止 let、const 重複宣告,直接排除即可。

錯誤類型:ReferenceError

ReferenceError 此類型錯誤通常是指「參考」找不到,當出現這類型錯誤時文字編輯器 “不一定” 出現錯誤(有裝 Linter 才會提示),所以時常會在執行階段才會看到這類型錯誤。

除錯重點:

  • 透過 Chrome 的提示修正
  • 在 JavaScript 撰寫環境中安裝 ESLint

ReferenceError: a is not defined

ReferenceError: a is not defined

語法參考錯誤:由於 a 變數未定義,所以在取用該變數時會出現未定義的提示,只要預先定義此變數即可。

不過還有另一種很常見的情況,當引用外部套件時出現「套件名稱 + is not defined」,這類型情況通常是外部資源沒有正確載入,請確保該資源有加入到此網站中。

以下範例來說,就是屬於 jQuery 沒有正確導入。

Uncaught ReferenceError: $ is not defined

錯誤類型:TypeError

TypeError 則是型別上的錯誤,文字編輯器一樣不會預先提示有錯,必須在執行環境時才會看到,這類型的錯誤通常是以下幾種:

  • 在 undefined、null 嘗試取得其屬性(ex: undefined 中取得屬性值)
  • 嘗試呼叫非函式變數或表達式(ex: 'text'()

除錯重點:在取得變數前方確認該變數當前的資料型別及結構

Uncaught TypeError: Cannot read property 'a' of undefined

var a;
console.log(a.a);

說明:該變數的值下無法找到特定的屬性,undefined、null 的值內無法在查找到其它的屬性,如果無法確認該變數是否為 undefined,可改寫其程式碼如下:

if (typeof a !== 'undefined') {
  console.log(a.a);
}

Uncaught TypeError: console.log(...) is not a function

console.log('a')
(function() {
  console.log('立即函式')
})()

說明:這段程式碼中看起來會是立即函式的錯誤,但卻出現了 console.log(...) is not a function。此錯誤主要是因為缺少了分號,因此將兩段程式碼合併為一行執行,運行的結果如下:

console.log('a')(function() { ... })()

當遇到此類型錯誤只要在兩者之間補上分號即可正常運作。

console.log('a');
(function() {
  console.log('立即函式')
})()

錯誤類型 RangeError

這是建立了超過長度的陣列或過度的執行函式(產生過多執行堆疊)所造成的錯誤,這類型則需要重新檢視程式碼的邏輯,是否會造成過度的硬體資源消耗(記憶體或運算資源)。

除錯重點:需重新檢視邏輯,如果必要可先刪除部分程式碼,先找出錯誤的片段後再進行除錯。

Uncaught RangeError: Maximum call stack size exceeded

(function a() {
  a();
})();

說明:函式呼叫時會產生一個執行堆疊,如果堆疊的過程中超過最大數量則會產生錯誤(函式內呼叫自己)。

此類錯誤也很常見,但卻不容易找到為何出錯,主要原因是執行堆疊超過環境的限制(運用框架中也很常見),如果遇到此錯誤建議改寫目前呼叫函式的方式。

結語

當 Chrome Console 出現錯誤時請維持正確的心態,新手常常會看到錯誤而緊張不知所措(畢竟從小紅被用紅字提醒就會感到緊張,深怕這個錯誤自己無法解決而影響到其他人)。

錯誤在撰寫程式碼中常見的過程,資深開發者與新手的差異是面對錯誤的經驗,同一個錯誤前幾次不清楚沒關係,都是經驗的累積,只要往後再次遇到相同的錯誤自然而然就能輕鬆面對。


下一篇
JavaScript 表達式觀念及運用 - JS Expression
系列文
前端常見問題攻略30

1 則留言

0
hannahpun
iT邦新手 5 級 ‧ 2020-09-25 22:39:52

超實用的一系列~~

卡斯伯 iT邦研究生 2 級 ‧ 2020-09-26 09:31:59 檢舉

感謝支持~

我要留言

立即登入留言