JavaScript >> Javascript 文檔 >  >> Tags >> Error

JavaScript 堆棧溢出錯誤

有時,我會在博客中介紹 JavaScript 瀏覽器的限制以及它們是如何呈現的。我從討論長時間運行的腳本對話框開始,然後轉向其他性能問題。我以為我已經涵蓋了大部分令人討厭且無法解釋的 JavaScript 限制,但上週我遇到了另一個值得討論的問題:堆棧溢出錯誤。

我已經寫過過多的遞歸會導致性能問題。大多數瀏覽器在自動取消腳本之前對允許的遞歸量有限制。這是一個與確定腳本是否長時間運行的限制不同的限制。遞歸調用的限制實際上更少,而與 JavaScript 調用堆棧的大小有關。

毫不奇怪,不同的瀏覽器有不同的調用堆棧大小。同樣不足為奇的是,他們用來確定調用堆棧的方法也各不相同。我可以測量的各種調用堆棧大小是(給或取,可能相差 1 或 2):

  • Internet Explorer 7:1,789
  • Firefox 3:3,000
  • Chrome 1:21,837
  • Opera 9.62:10,000
  • Safari 3.2:500

有人說,但我無法證實,IE 和 Opera 的調用堆棧大小在某種程度上與系統上的 RAM 量有關。默認情況下,所有其他瀏覽器都有此設置。還值得注意的是,WebKit 似乎有更高的限制,而 Safari 對 JavaScript 引擎施加了更嚴格的限制。

有兩種常見情況可以達到此限制。第一種是簡單的遞歸,如:

function recurse(){
    recurse();
}

recurse();

第二個是更狡猾且更難識別的問題,尤其是在大型代碼庫中,其中兩個函數相互調用,例如:

function doSomething(){
    doSomethingElse();
}

function doSomethingElse(){
    doSomething();
}

doSomething();

在每種情況下,瀏覽器最終都會停止您的代碼並(希望)顯示有關該問題的消息:

  • Internet Explorer 7:“第 x 行的堆棧溢出”
  • Firefox 3:“遞歸過多”
  • Chrome 1:不適用
  • Opera 9.62:“中止(控制堆棧溢出)”
  • Safari 3.2:“RangeError:超出最大調用堆棧大小。”

Chrome 是唯一不顯示指示問題的消息的瀏覽器。如果您看到這些錯誤消息中的任何一個彈出,這意味著涉及兩種模式之一併且需要更改。這個錯誤通常有一個行號和文件名,因此調試起來相當簡單。

堆棧溢出錯誤最有趣的部分可能是它們是某些瀏覽器中的實際 JavaScript 錯誤,因此可以使用 try-catch 進行捕獲 陳述。異常類型因所使用的瀏覽器而異。在 Firefox 中,它是一個 InternalError ,在 Safari 和 Chrome 中,它是 RangeError ,並且 Internet Explorer 會拋出一個通用的 Error type(Opera 不會拋出錯誤,它只是停止 JavaScript 引擎)。所以,可以這樣做:

try {
    recurse();
} catch (ex){
    alert("Too much recursion!");
}

如果不被捕獲,這些錯誤會像任何其他錯誤一樣冒泡(在 Firefox 中,它最終出現在 Firebug 控制台中,Safari/Chrome 出現在控制台中),但 Internet Explorer 除外。 IE 不僅會顯示 JavaScript 錯誤,還會顯示一個醜陋的對話框,看起來就像帶有堆棧溢出消息的警報。

現在,僅僅因為幾乎所有瀏覽器都可能捕獲此錯誤並不意味著您應該這樣做。即使存在堆棧溢出錯誤的可能性,任何代碼都不應該最終投入生產。此類實例表明代碼設計不佳,應重新評估和/或重新設計以避免此錯誤。將此帖子視為調試此問題的幫助,而不是誘捕和掩飾它的許可。


Tutorial JavaScript 教程
  1. 7 個開源測試自動化框架

  2. 有沒有辦法使用 JavaScript 以納秒為單位獲取當前時間?

  3. Javascript Date.getTime() 的 C# 版本

  4. 如何在 React 中處理表單驗證?

  5. 另一個 React Firebase 教程?

  6. 使用 esbuild 構建庫

  7. 我是如何學習 this.reduce();

  1. 使用 nuxt-speedkit 進行 Lighthouse 性能優化

  2. 在您提出每個拉取請求後,請振作起來!

  3. 如何使用 MongoDB、Express、Vue 和 Node(MEVN 堆棧)構建全棧 RPG 角色生成器

  4. 餘燼時報 - 第 147 期

  5. 使用 Nx Workspace 生成器構建新的博客文章

  6. 如何禁用 Angulars 對 URL 的內置清理

  7. 高級 TypeScript 練習 - 答案 7

  1. 使用 Red Hat CodeReady Dependency Analytics 和 Snyk Intel 進行漏洞分析

  2. 如何使用 Vanilla JavaScript 創建數據綁定

  3. 使用 jQuery 的顏色漸變菜單

  4. 使用 CloudFront 在 AWS S3 上託管 Angular 應用程序