10個JavaScript最常出現的錯誤

2020-09-04 WEB開發李家靖

為了便於閱讀,每個錯誤都被縮短了,讓我們更深入地研究每一個問題,以確定是什麼導致了這些問題,以及如何避免產生這些問題。

1. Uncaught TypeError: Cannot read property

如果你是一個JavaScript開發人員,你可能已經看到過這個錯誤。當你讀取屬性或在未定義對象上調用方法時,Chrome中就會發生這種情況。你可以在Chrome開發者控制臺中輕鬆進行測試。

發生這種情況的原因有很多,但常見的原因是渲染UI組件時狀態初始化不當。讓我們來看一個在現實應用中如何發生這種情況的示例。我們將選擇React,但是不正確初始化的相同原理也適用於Angular,Vue或任何其他框架。

class Quiz extends Component { componentWillMount() { axios.get(&39;).then(res => { this.setState({items: res.data}); }); } render() { return ( <ul> {this.state.items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ); }}

這裡有兩件重要的事情要意識到:

  • 組件的狀態(例如 this.state)以 undefined 狀態開始使用。
  • 當你異步獲取數據時,無論數據是在構造函數 componentWillMount 還是 componentDidMount 中獲取,組件都將在數據加載之前至少渲染一次。當Quiz第一次渲染時,this.state.items 是 undefined。這反過來又意味著ItemList會得到未定義的items,你會在控制臺中得到一個錯誤——&39;map&34;的錯誤。

這很容易解決,最簡單的方法:在構造函數中使用合理的默認值初始化狀態。

class Quiz extends Component { // 添加了這個: constructor(props) { super(props); this.state = { items: [] // 默認值 }; } componentWillMount() { axios.get(&39;).then(res => { this.setState({items: res.data}); }); } render() { return ( <ul> {this.state.items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ); }}

你的應用程式中的實際代碼可能會有不同,但我希望已經給了你足夠的線索,讓你在你的應用程式中修復或避免這個問題。如果沒有,請繼續閱讀,因為我將在下面介紹有關相關錯誤的更多示例。


2. TypeError: 『undefined』 is not an object (evaluating

這是在Safari中讀取屬性或調用undefined對象上的方法時發生的錯誤,你可以在Safari開發者控制臺中非常輕鬆地進行測試。這基本上與上述針對Chrome的錯誤相同,但Safari使用了不同的錯誤消息。

3. TypeError: null is not an object (evaluating

這是在Safari中讀取屬性或調用null對象上的方法時發生的錯誤,你可以在Safari開發者控制臺中非常輕鬆地進行測試。

有趣的是,在JavaScript中,null和undefined不相同,這就是為什麼我們看到兩個不同的錯誤消息的原因。undefined通常是尚未分配的變量,而null表示該值為空白。 要驗證它們是否相等,請嘗試使用嚴格相等運算符。

在實際示例中可能發生這種錯誤的一種方式是,在加載元素之前嘗試在JavaScript中使用DOM元素,這是因為DOM API對於空白的對象引用返回null。

任何執行和處理DOM元素的JS代碼都應在創建DOM元素後執行。JS代碼按照HTML格式從上到下進行解釋,所以,如果在DOM元素之前有一個標籤,那麼在瀏覽器解析HTML頁面的時候,腳本標籤內的JS代碼就會被執行。如果在加載腳本之前尚未創建DOM元素,則會出現此錯誤。

在此示例中,我們可以通過添加事件偵聽器來解決該問題,該事件偵聽器將在頁面準備就緒時通知我們。一旦觸發了 addEventListener,init() 方法就可以使用DOM元素。

<script> function init() { var myButton = document.getElementById(&34;); var myTextfield = document.getElementById(&34;); myButton.onclick = function() { var userName = myTextfield.value; } } document.addEventListener(&39;, function() { if (document.readyState === &34;) { init(); } });</script><form> <input type=&34; id=&34; placeholder=&34; /> <input type=&34; id=&34; value=&34; /></form>

4. (unknown): Script error

當未捕獲的JavaScript錯誤違反跨源策略跨越域邊界時,將發生腳本錯誤。例如,如果你將你的JavaScript代碼託管在CDN上,任何未被捕獲的錯誤(冒泡到window.onerror處理程序中的錯誤,而不是在try-catch中被捕獲的錯誤)都會被報告為 &34;,而不是包含有用的信息。這是一種瀏覽器安全措施,旨在防止跨域傳遞數據,否則該域將無法通信。

要獲取真實的錯誤消息,請執行以下操作。

發送Access-Control-Allow-Origin標頭

將 Access-Control-Allow-Origin 標頭設置為 * 表示可以從任何域正確訪問資源。你可以根據需要將 * 替換為您的域:例如,Access-Control-Allow-Origin:www.example.com。但是,處理多個域比較複雜,如果使用CDN可能會出現緩存問題,那麼可能不值得花費精力。

以下是一些有關如何在各種環境中設置此標頭的示例:

Apache

在將提供JavaScript文件的文件夾中,創建一個具有以下內容的 .htaccess 文件:

Header add Access-Control-Allow-Origin &34;

Nginx

將add_header指令添加到提供JavaScript文件的location塊中:

location ~ ^/assets/ { add_header Access-Control-Allow-Origin *;}

HAProxy

將以下內容添加到提供JavaScript文件的asset後端:

rspadd Access-Control-Allow-Origin:\ *

在腳本標籤上設置crossorigin =「 anonymous」

在你的HTML原始碼中,對於您設置了 Access-Control-Allow-Origin 標頭的每個腳本,在script標記上設置crossorigin=&34;。在script標記上添加 crossorigin 屬性之前,請確保已驗證是否已為腳本文件發送了標頭。在Firefox中,如果存在 crossorigin 屬性,但沒有 Access-Control-Allow-Origin 標頭,則不會執行腳本。

5. TypeError: Object doesn’t support property

這是在IE中發生的錯誤,當您調用undefined的方法時,你可以在IE開發人員控制臺中對此進行測試。

這等效於Chrome中的錯誤「 TypeError:『undefined』 is not a function」。是的,對於相同的邏輯錯誤,不同的瀏覽器可能具有不同的錯誤消息。

這是IE在採用JavaScript命名空間的Web應用程式中常見的問題,在這種情況下,99.9%的問題是IE無法將當前名稱空間中的方法綁定到 this 關鍵字。

例如,如果你的JS命名空間 Rollbar 使用 isAwesome 方法。通常,如果你在 Rollbar 名稱空間中,則可以使用以下語法調用 isAwesome 方法:

this.isAwesome();

Chrome,Firefox和Opera將很樂意接受此語法。另一方面,IE則不會。因此,在使用JS命名空間時,最安全的方法是用實際的命名空間作為前綴。

Rollbar.isAwesome();

6. TypeError: 『undefined』 is not a function

這是在Chrome中發生的錯誤,當你調用undefined的函數時。你可以在Chrome開發者控制臺和Mozilla Firefox開發者控制臺中對此進行測試。

隨著這些年來JavaScript的編碼技術和設計模式越來越複雜,在回調和閉包中的自引用作用域也相應地增多,這也是相當常見的這種或那種混亂的根源。

考慮以下示例代碼片段:

function clearBoard(){ alert(&34;);}document.addEventListener(&34;, function(){ this.clearBoard(); // 這個 &34; 是什麼?});

如果執行上述代碼,然後單擊該頁面,則會導致以下錯誤「 Uncaught TypeError:this.clearBoard not a function」。原因是正在執行的匿名函數是在文檔的上下文中,而 clearBoard 是在 window 中定義的。

傳統的、與舊瀏覽器兼容的解決方案是簡單地將對它的引用保存在一個變量中,然後閉包可以繼承這個變量。例如:

var self = this;document.addEventListener(&34;, function(){ self.clearBoard();});

另外,在較新的瀏覽器中,可以使用 bind() 方法傳遞正確的引用:

document.addEventListener(&34;,this.clearBoard.bind(this));

7. Uncaught RangeError: Maximum call stack

這是Chrome瀏覽器在幾種情況下出現的錯誤,一種是調用不終止的遞歸函數。你可以在Chrome開發者控制臺中對此進行測試。

如果將值傳遞給超出範圍的函數,也可能會發生這種情況。許多函數的輸入值僅接受特定範圍的數字,例如,Number.toExponential(digits) 和 Number.toFixed(digits) 接受0到20之間的數字,而Number.toFixed(digits) 接受1到21之間的數字。

var a = newArray(4294967295); //OKvar b = newArray(-1); //range errorvar num = 2.555555;document.writeln(num.toExponential(4)); //OKdocument.writeln(num.toExponential(-2)); //range error!num = 2.9999;document.writeln(num.toFixed(2)); //OKdocument.writeln(num.toFixed(25)); //range error!num = 2.3456;document.writeln(num.toPrecision(1)); //OKdocument.writeln(num.toPrecision(22)); //range error!

8. TypeError: Cannot read property 『length』

這是Chrome瀏覽器中發生的錯誤,因為讀取undefined的變量的length屬性,你可以在Chrome開發者控制臺中進行測試。

通常情況下,你可以在數組上找到定義的長度,但如果數組沒有初始化或者變量名被隱藏在其他上下文中,你可能會遇到這個錯誤。通過以下示例讓我們了解此錯誤。

var testArray= [&34;];function testFunction(testArray) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction();

當你聲明一個帶參數的函數時,這些參數就變成了局部參數。這意味著即使你具有名稱為 testArray 的變量,函數內具有相同名稱的參數仍將被視為局部參數。

你可以通過兩種方式解決問題:

刪除函數聲明語句中的參數(事實證明,你想訪問那些在函數外部聲明的變量,因此你不需要為函數使用參數)

var testArray = [&34;];/* 前置條件:在函數外部定義testArray */function testFunction(/* No params */) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction()

調用函數,將我們聲明的數組傳遞給它。

var testArray = [&34;];function testFunction(testArray) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction(testArray);

9. Uncaught TypeError: Cannot set property

當我們嘗試訪問未定義的變量時,它總是返回 undefined,我們無法獲取或設置任何 undefined 屬性。在這種情況下,應用程式將引發「 Uncaught TypeError:Cannot set property」。

例如,在Chrome瀏覽器中:

如果 test 對象不存在,則錯誤將引發「 Uncaught TypeError:Cannot set property」。

10. ReferenceError: event is not defined

當您嘗試訪問undefined 或超出當前範圍的變量時,將引發此錯誤。你可以在Chrome瀏覽器中非常輕鬆地對其進行測試。

如果你在使用事件處理系統時收到這個錯誤,請確保你使用傳入的事件對象作為參數。IE等較舊的瀏覽器會提供全局變量事件,而Chrome會自動將事件變量附加到處理程序。Firefox不會自動添加它。jQuery之類的庫試圖規範這種行為,儘管如此,最好還是使用傳遞給事件處理程序函數的方法。

document.addEventListener(&34;, function (event) { console.log(event);})

總結

事實證明,其中許多都是null或undefined的錯誤。如果使用嚴格的編譯器選項,像Typescript這樣的靜態類型檢查系統可以幫助你避免使用它們。它可以警告你,如果一個類型是預期的,但還沒有被定義。

相關焦點

  • 如何避免 JavaScript 開發者常犯的 9 個錯誤?
    但很多初學者都會犯一些常見的錯誤。在這篇文章中,我們將介紹 9 個常見的錯誤(或者說不好的實踐)以及它們的解決方案,幫助你成為更好的 JavaScript 開發者。secondNumber); }, 200);}addTwoNumbers();// 15this 指代錯誤在 JavaScript 中,this 是一個常被誤解的概念。
  • 回答一下這 10 個最常見的 Javascript 問題
    為初學者介紹一下這 10 個最常被問到的 Javascript 問題在本文中,我收集了關於Javascript 最常被問到的 10 個問題及其答案。這10 個問題大多涉及 Javascript 的基礎知識,所以如果你剛剛開始學習 JS,最好理解並掌握它們並。這個 10 問題涉及 JS 中閉包、promise,變量提升、類等等。
  • 10個基於瀏覽器的javascript在線debugging工具
    10個基於瀏覽器的javascript在線debugging工具 調試Javascript可能是web開發中最讓人鬱悶的事情。所以這裡我們絕定來尋找一些好的工具來幫助大家調試。
  • 分享10個 javascript 在線 debugging 工具
    日期:2012/01/18  來源:GBin1.com調試Javascript可能是web開發中最讓人鬱悶的事情。所以這裡我們絕定來尋找一些好的工具來幫助大家調試。
  • Python程式設計師最常犯的10個錯誤,你中招了嗎?
    鑑於此,本文列出了Python開發人員常犯的10個小錯誤,資深程序猿也難免會中招哦。除非處理得當,否則就會導致Python出現錯誤。在Python2.x中,except Exception語句中變量e可用來把異常信息綁定到第二個可選參數上,以便進一步查看異常的情況。因此,在上述代碼中,except語句並沒有捕捉到IndexError異常;而是將出現的異常綁定到了參數IndexError中。
  • PHP初學者最常遇到的8個錯誤及解決思路!
    PHP由於即可以面向過程也可以面向對象開發,被廣泛認為是最容易學習的程式語言。在源碼時代的全棧學科,PHP被作為全棧的後端語言。初學者在學習程式語言往往是從面向過程開始的,這樣更容易理解。但是在學習PHP的過程中時常會遇到各種報錯,全是英文,對於英文基礎差的同學會很不友好。本篇為大家收集了初學者最常遇到的8個報錯,並為大家提供對應的解決思路。
  • Java開發最常犯的10個錯誤,打死都不要犯!
    個Java開發人員最常犯的錯誤。推薦:HashMap 和 Hashtable 的 6 個區別!5、使用集合原始類型(raw type)在Java中,原始類型(raw type)和無界通配符類型很容易讓人混淆。舉個Set的例子,Set是原始類型,而Set是無界通配符類型。
  • 1000+ 個項目的10大JavaScript錯誤
    這反過來又意味著ItemList會得到未定義的items,你會在控制臺中得到一個錯誤——&39;map&34;的錯誤。這很容易解決,最簡單的方法:在構造函數中使用合理的默認值初始化狀態。如果在加載腳本之前尚未創建DOM元素,則會出現此錯誤。在此示例中,我們可以通過添加事件偵聽器來解決該問題,該事件偵聽器將在頁面準備就緒時通知我們。一旦觸發了 addEventListener,init() 方法就可以使用DOM元素。
  • 10 種 JavaScript 中常見的錯誤
    前言查看了數千個項目後,發現了 10 個最常見的 JavaScript 錯誤。我們會告訴你什麼原因導致了這些錯誤,以及如何防止這些錯誤發生。如果你能夠避免落入這些 「陷阱」,你將會成為一個更好的開發者。
  • 盤點10個英文Email最常犯的錯誤
    今天要談的是商業英文幾組慣用的搭配,錯誤的搭配不見得就是文法錯誤,但搭對了,就會有自然流暢的專業。1. 謝謝你提醒我們注意。錯誤:Thank you for bringing this to our notice.
  • javascript的編寫規範有哪些?
    它對應不同的 JavaScript 語境會做更加嚴格的錯誤檢查。嚴格模式也確保了 javascript 代碼更加的健壯,運行的也更加快速。嚴格模式會阻止使用在未來很可能被引入的預留關鍵字。你應該在你的腳本中啟用嚴格模式,最好是在獨立的 IIFE 中應用它。避免在你的腳本第一行使用它而導致你的所有腳本都啟動了嚴格模式,這有可能會引發一些第三方類庫的問題。
  • 5 月份最熱門的 10 個 JavaScript 庫
    Chronoline.js是一個javascript的類庫用來幫助開發者創建一個按時間來展示的時間線。 整個時間線水平方向顯示,我們可以方便的顯示任何時間長度的事件,並且提供一個tooltip來展示事件詳細內容。
  • 10個優化代碼的CSS和JavaScript工具
    10個優化代碼的CSS和JavaScript工具 如果你想在保持文件的時候或執 行的階段lint代碼,那麼linting工具也可以如你所願。這取決於個人的選擇。如果你正在找尋用於CSS和JavaScript最好的 linting工具,那麼請繼續閱讀。
  • 9 個JavaScript 技巧
    但是,如果我們不知道深度怎麼辦,則需要將其全部展平,只需將Infinity作為參數即可 const arrays = [[10], 50, [100, [2000, 3000, [40000]]]]arrays.flat(Infinity)// [ 10, 50
  • 快改掉這15個最常犯的「中式英文」錯誤
    現在就讓我們來看看15個常見的Chinglish!1. 歡迎你來到我家錯誤:Welcome you to my house.正確:Welcome to my house.Welcome to本身就是歡迎你的意思,再多加一個you在外國人聽來就變「歡迎你你」了。2. 我會永遠記住你錯誤:I will remember you forever.
  • javascript流程語句
    3.結構化程序是由若干個基本結構組合而成,每一個結構可以包含若干條語句和其它基本結構。共有三種基本結構:順序、分支、循環順序:從上朝下執行的代碼就是順序選擇:根據不同的情況,執行對應代碼循環:重複做一件事情順序結構 順序結構是最簡單的程序結構,它是由若干個依次執行的處理步驟組成的。
  • 開發者最容易犯的13個JavaScript錯誤
    開發者最容易犯的JavaScript錯誤,總結出13個。這些當中可能少不了你犯的錯誤^_^。我們描述了這些陋習,並列出來解決辦法,希望對開發者有幫助。 1.for..數組維度  Array dimensions 舉例 var myArray = new Array(10); 這裡有兩個不同的問題。首先,開發者嘗試創建一個包含10項的數組,這將創建10個空槽的陣列。然而,如果你試圖得到一數組項,你將得到」未定義「的結果。換句話說,效果就像你沒有保存內存空間。沒有真正的好原因來預定義數組長度。
  • Influencer Marketing最常犯的六個錯誤
    以下為大家介紹Influencer Marketing最常犯的六個錯誤。 錯誤一:沒有制定策略的營銷活動 最常見的錯誤就是執行了一個YouTube的Influencer Marketing營銷計劃,重金禮聘邀請具有影響力的YouTuber,但想要Youtuber帶來的實際影響力卻非常模糊,例如希望通過這個影片可以觸及到10萬的用戶、3萬個贊數
  • 盤點:4月份熱門的10個JavaScript開源工具
    Jitsi是當最功能最完整的高級通信工具,可以在同一個軟體中連到Facebook、GoogleTalk、XMPP、Windows Live、Yahoo!、AIM和ICQ進行通信。3、next.jsNext.js是一個用於React應用的極簡的服務端渲染框架。
  • 軟體史上最逗比的10個錯誤信息
    Windows 10 安裝錯誤如果你認為這些事情只會在老版本的作業系統中出現,那你就錯了。6.Windows Phone安裝盤錯誤隨著時間的推移,這種錯誤開始出現在任何一部使用Windows Phone作業系統的手機裡。