**
javascript錯誤處理
**
由于javascript本身是動態語言,而且沒有固定的開發工具,因此他普遍認為是最難以調試的語言,在ECMAScript3新增了try-catch和throw以及一些錯誤類型,讓開發人員能適當的處理錯誤,緊接著web瀏覽器也出現了一些javascript的調試程序和工具
錯誤類型:
執行代碼期間可能會發生的錯誤類型有多種,每種錯誤都有對應的錯誤類型,如下
- Error 普通錯誤類型
- EvalError 類型的錯誤一般使用了eval函數而發生的異常
- RangeError 類型的錯誤一般在數值超出相應的范圍時觸發
- ReferenceError 這種比較常見 訪問的變量不存在
- SyntaxError 這種一般很少見
- TypeError 一般是保存變量存在其他的類型
- URLError 在使用encodeURL或decodeURL函數時,url格式不正確會報這個URLError錯誤
處理錯誤
我們在項目中最常見的就是使用try-catch來處理
try{.
// 一般是我們的邏輯代碼,可能會導致錯誤的代碼}catch{
// 在錯誤發生時會在這里進行處理
}// 注意catch后面還有一個finally子句
function testFinally(){try{return 3}catch{. return 2}finally{reutrn 1}
}
// finally子句他的機制是不管try或catch執不執行,最后finally都會去執行 所以這段代碼// 最后返回的結果是 1 而不是 2
拋出錯誤
與tru-catch語句相配合的又一個throw操作符,用于隨時拋出自定義錯誤,拋出錯誤時,必須要賦值,至于這個值是什么類,是不做要求的。在執行throw操作符時,代碼會立即停止執行,僅當有try-catch語句捕獲到被拋出的值時,才會繼續執行
throw 1234
throw [1,2,3,4]
throw true
....
一般情況下可以通過某種內置錯誤模擬瀏覽器的錯誤,每種錯誤類型只需要接受一個參數
throw new Error('something bad happend')
throw new TypeError('what type of variable do you take me for ?')
...
還可以創建一個自定義錯誤類型
function CustomerError(message){this.name = 'CustomError'this.message = message
}
CustomerError.prototype = new Error()
throw new CustomerError ('my message')
錯誤事件
任何沒有通過tru-catch處理的錯誤都會觸發window對象的error事件,而且這事件對于chrome firefox IE 都是支持的。具體方法如下:
// onerror接受三個參數 錯誤消息 錯誤所在的url 某個文本第多少行發生的錯誤,對于我們現在通過vue 或react框架大包之后我們一般只有message這個參數對我們開發人員有人,其他的可能意義不大,這里提一下如果要定位到線上具體的文件的錯誤可以使用sourceMap來定位,這里就不多廢話了。
window.onerror = function (message,url,line){console.log(message)
}
注意常見的錯誤類型
1.數據轉換錯誤
我們使用的非常多的 == 和 != 還有 === 等這些需要在開發的過程中注意
5 == ‘5’ // true
5 === ‘5’ // false
1 == true // true
1 === true // false
...// 這個看似沒有問題,但是一旦出入的不是數字,可能程序就直接掛了
function concat (str1,str2,str3){let result = str1 + str2if(str3){result += str3}return result
}再比如數據類型的錯誤:
function resverseSort(values){if(values){ // 這是只要有值過來就過了 values.sort()}if(values != null) { // 不靠譜 values.sort()} if(typeof value.sort == 'function') { // 不靠譜 values.sort()} if(values instanceof Array) { // 這種是比較穩妥的 values.sort()}
}// 通信錯誤
一般是在與后端對接的時候URL的格式不正確或者發送的數據有問題造成的。
對于URL地址,沒有使用encodeURLComponent()造成的問題
可以寫一個簡單的函數 function addQueryStringArg(url,name,value){if(url.indexOf("?") == -1){url+= "?"}else{url += "&"}url += encodeURLComponent(name) + '=' + encodeURLComponent(value)
}
const url = 'http://www.some.com'
let newUrl = addQueryStringArg(url,'redir','http://www.something.com?a=1&b=2')
把錯誤記錄到服務器
要記錄js的錯誤記錄系統,先要在服務器上創建一個頁面,或者一個服務入口,再來處理錯誤數據
這個所有瀏覽器都支持,且能夠跨域,可以處理多臺服務器的記錄。
function logError(sev,msg){var img = new Image()img.src = "log.php?sev=" + encodeURLComponent(sev) + "&msg="+ encodeURLComponent(msg)
}一般如果想要記錄,只要出現try-catch的語句可以在catch里面調用這個方法
try{
}catch(err){
logError('nonfatal' , '某某錯誤失敗:'+ err.message)
}