您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關怎么在JavaScript中捕獲錯誤,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
1、能夠嵌入動態文本于HTML頁面。2、對瀏覽器事件做出響應。3、讀寫HTML元素。4、在數據被提交到服務器之前驗證數據。5、檢測訪客的瀏覽器信息。6、控制cookies,包括創建和修改等。7、基于Node.js技術進行服務器端編程。
使用
try{ //code.... }catch(err){ //error handling }finally{ //no matter what happens in the try/catch (error or no error), this code in the finally statement should run. }
邏輯
try...catch 僅適用于運行時錯誤,解釋階段錯誤無法正常工作
try{ {{{{{{{ }catch(err){ console.error(err) } //引擎在‘parse-time'出錯,導致無法理解代碼,因此無法捕捉
try...catch 只能同步工作
try{ setTimeout(function(){ undefinedVariable; },1000) }catch(err){ console.error(err) } //setTimeout的回調函數執行時,引擎已經離開try...catch結構
finally 能讓try塊中的return語句失效
function test(){ try { return 1; } catch(error) { return 2; } finally { return 3; } } console.log(test()); //3
當程序發生error,js內部會生成一個包含error細節的對象,該對象會被作為參數傳進catch
對于所有內置錯誤,錯誤對象具有兩個主要屬性
name 錯誤類型
message 文本類型的錯誤信息
stack (非標準屬性)發生錯誤時的調用棧信息,主要用于調試
try { lalala; // error, variable is not defined! } catch (err) { alert(err.name); // ReferenceError alert(err.message); // lalala is not defined alert(err.stack); // ReferenceError: lalala is not defined at (...call stack) // Can also show an error as a whole // The error is converted to string as "name: message" alert(err); // ReferenceError: lalala is not defined }
理論上,我們可以throw任何東西作為錯誤對象,但最好的習慣是throw一個具有name,message的對象,以便和內置錯誤對象保持兼容
番外:內置的錯誤對象
對象 | 含義 |
---|---|
ReferenceError | 引用未定義變量時觸發 |
SyntaxError | 使用不合法的語法結構時觸發 |
TypeError | 值得類型非預期時觸發 |
URIError | 錯誤使用全局URI函數如encodeURI()、decodeURI()等時觸發 |
RangeError | 對Array構造函數使用錯誤的長度值,對Number.toExponential()、Number.toFixed()或Number.toPrecision()使用無效數字等 |
EvalError | 全局函數eval()中發生的錯誤 |
catch錯誤不單單是為了防止程序掛掉,更重要的目的是方便調試,找bug,所以對錯誤的處理策略,稍微可以體現出碼者的優雅性
俗話說的好,碼者,人恒雅也,盡量遵循一個原則,catch只處理自己知道的錯誤
舉個梨子
let json = '{ "age": 30 }'; try{ let user = JSON.parse(json); alert( user.name ); } catch (err) { console.error('JSON Error:'+err); }
上述例子的catch策略能保證程序正常,因為catch塊能catch內部所有的錯誤,無論是JSON.parse出錯還是user.name不存在報錯,都能被catch到,但兩種錯誤都用同一種打印是不利于調試的,寫成下面這樣會好一點
let json = '{"age":30}' try{ let user = JSON.parse(json); alert(user.name) }catch(err){ if(err instanceof SyntaxError){ console.error('JSON Error:'+err); } else throw err; }
每個catch塊處理自己知道得,可能會出現得錯誤,就是說,編程人員在編程的時候,catch那些預料到的錯誤,而將可能自己沒料到的錯誤拋到外面。
眾所周知,Promise是會吞掉error的,因為promise的實現就在內部對所有error進行了捕獲,且捕獲到的error不是向外拋出(外指promise之外),而是沿著鏈找到最近的onreject回調傳入,所以promise的錯誤處理只有兩種辦法
設置onreject回調
全局捕獲
舉個栗子
try{ new Promise((resolve,reject)=>{ throw new Error('promise error') }).catch(()=>{ //錯誤在最近的onreject回調被捕獲 console.error(err); }) }catch(err){ //永遠不會執行,promise吞掉error console.error(err); }
另外需要注意,無論是執行者函數(executor)和還是 promise 的處理程序(handler),內部發生的錯誤統統吞掉,相當于被隱式catch,error會自動找到最近的onreject回調傳進去
try{ new Promise((resolve,reject)=>{ resolve(); }).then(()=>{ throw new Error('promise then error'); }).catch((err){ console.error(err); }) }catch(err){ //地球毀滅之前都不會執行 console.error(err) }
同理,在錯誤找到onreject傳進去之前,經過的then注冊的onfulfilled回調統統失效,直到找到onreject回調,處理之后,onreject回調之后的onfulfilled回調才正常
try { new Promise((resolve, reject) => { throw new Error('promise error') }).then((ret) => { //錯誤沒有處理,失效 console.log('then1:' + ret) }).catch((err) => { //錯誤處理了,后序正常 console.error(err); return 'handled' }).then((ret) => { //正常執行 console.log('then2' + ret); }) } catch (err) { //同樣的,人類毀滅之前都不會執行 console.error(err) } // Error:promise error //then2handled
那整條鏈一個catch都沒設置會怎么樣呢?
那這個error就會擊穿地心,一直穿透到全局,根據宿主環境的不同觸發不同的全局事件,比如說瀏覽器中會觸發 unhandledrejection事件,node環境中也會觸發unhandledRejection事件,一般會對這事件進行監聽,再顯示信息給編程人員或者用戶
番外1:chromium / v8 / v8 / 3.29.45 的 Promise內部錯誤捕捉
關于怎么在JavaScript中捕獲錯誤就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。