国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端開發(fā)中的Error以及異常捕獲

Mr_houzi / 3433人閱讀

摘要:前端開發(fā)中的中的中,是一個(gè)構(gòu)造函數(shù),通過它創(chuàng)建一個(gè)錯(cuò)誤對(duì)象。是核心對(duì)象,表示調(diào)用一個(gè)時(shí)發(fā)生的異常。將回調(diào)函數(shù)包裹一層接下來可以將統(tǒng)一進(jìn)行處理。中的錯(cuò)誤捕獲在以前,可以使用來處理捕獲的錯(cuò)誤。研究結(jié)果在這里中的錯(cuò)誤捕獲的源碼中,在關(guān)

本文首發(fā)于公眾號(hào):符合預(yù)期的CoyPan
寫在前面

在前端項(xiàng)目中,由于JavaScript本身是一個(gè)弱類型語言,加上瀏覽器環(huán)境的復(fù)雜性,網(wǎng)絡(luò)問題等等,很容易發(fā)生錯(cuò)誤。做好網(wǎng)頁錯(cuò)誤監(jiān)控,不斷優(yōu)化代碼,提高代碼健壯性是一項(xiàng)很重要的工作。本文將從Error開始,講到如何捕獲頁面中的異常。文章較長,細(xì)節(jié)較多,請(qǐng)耐心觀看。

前端開發(fā)中的Error JavaScript中的Error

JavaScript中,Error是一個(gè)構(gòu)造函數(shù),通過它創(chuàng)建一個(gè)錯(cuò)誤對(duì)象。當(dāng)運(yùn)行時(shí)錯(cuò)誤產(chǎn)生時(shí),Error的實(shí)例對(duì)象會(huì)被拋出。構(gòu)造一個(gè)Error的語法如下:

// message: 錯(cuò)誤描述
// fileName: 可選。被創(chuàng)建的Error對(duì)象的fileName屬性值。默認(rèn)是調(diào)用Error構(gòu)造器代碼所在的文件的名字。
// lineNumber: 可選。被創(chuàng)建的Error對(duì)象的lineNumber屬性值。默認(rèn)是調(diào)用Error構(gòu)造器代碼所在的文件的行號(hào)。

new Error([message[, fileName[, lineNumber]]])
ECMAScript標(biāo)準(zhǔn):

Error有兩個(gè)標(biāo)準(zhǔn)屬性:

Error.prototype.name :錯(cuò)誤的名字

Error.prototype.message:錯(cuò)誤的描述

例如,在chrome控制臺(tái)中輸入以下代碼:

var a = new Error("錯(cuò)誤測(cè)試");
console.log(a); // Error: 錯(cuò)誤測(cè)試
                // at :1:9
console.log(a.name); // Error
console.log(a.message); // 錯(cuò)誤測(cè)試

Error只有一個(gè)標(biāo)準(zhǔn)方法:

Error.prototype.toString:返回表示一個(gè)表示錯(cuò)誤的字符串。

接上面的代碼:

a.toString();  // "Error: 錯(cuò)誤測(cè)試"
非標(biāo)準(zhǔn)的屬性

各個(gè)瀏覽器廠商對(duì)于Error都有自己的實(shí)現(xiàn)。比如下面這些屬性:

Error.prototype.fileName:產(chǎn)生錯(cuò)誤的文件名。

Error.prototype.lineNumber:產(chǎn)生錯(cuò)誤的行號(hào)。

Error.prototype.columnNumber:產(chǎn)生錯(cuò)誤的列號(hào)。

Error.prototype.stack:堆棧信息。這個(gè)比較常用。

這些屬性均不是標(biāo)準(zhǔn)屬性,在生產(chǎn)環(huán)境中謹(jǐn)慎使用。不過現(xiàn)代瀏覽器差不多都支持了。

Error的種類

除了通用的Error構(gòu)造函數(shù)外,JavaScript還有7個(gè)其他類型的錯(cuò)誤構(gòu)造函數(shù)。

InternalError: 創(chuàng)建一個(gè)代表Javascript引擎內(nèi)部錯(cuò)誤的異常拋出的實(shí)例。 如:?"遞歸太多"。非ECMAScript標(biāo)準(zhǔn)。

RangeError: 數(shù)值變量或參數(shù)超出其有效范圍。例子:var a = new Array(-1);

EvalError: 與eval()相關(guān)的錯(cuò)誤。eval()本身沒有正確執(zhí)行。

ReferenceError: 引用錯(cuò)誤。 例子:console.log(b);

SyntaxError: 語法錯(cuò)誤。例子:var a = ;

TypeError: 變量或參數(shù)不屬于有效范圍。例子:[1,2].split(".")

URIError: 給?encodeURI或?decodeURl()傳遞的參數(shù)無效。例子:decodeURI("%2")

當(dāng)JavaScript運(yùn)行過程中出錯(cuò)時(shí),會(huì)拋出上8種(上述7種加上通用錯(cuò)誤類型)錯(cuò)誤中的其中一種錯(cuò)誤。錯(cuò)誤類型可以通過error.name拿到。

你也可以基于Error構(gòu)造自己的錯(cuò)誤類型,這里就不展開了。

其他錯(cuò)誤

上面介紹的都是JavaScript本身運(yùn)行時(shí)會(huì)發(fā)生的錯(cuò)誤。頁面中還會(huì)有其他的異常,比如錯(cuò)誤地操作了DOM。

DOMException

DOMException是W3C DOM核心對(duì)象,表示調(diào)用一個(gè)Web Api時(shí)發(fā)生的異常。什么是Web Api呢?最常見的就是DOM元素的一系列方法,其他還有XMLHttpRequest、Fetch等等等等,這里就不一一說明了。直接看下面一個(gè)操作DOM的例子:

var node = document.querySelector("#app");
var refnode = node.nextSibling;
var newnode = document.createElement("div");
node.insertBefore(newnode, refnode);

// 報(bào)錯(cuò):Uncaught DOMException: Failed to execute "insertBefore" on "Node": The node before which the new node is to be inserted is not a child of this node.

單從JS代碼邏輯層面來看,沒有問題。但是代碼的操作不符合DOM的規(guī)則。

DOMException構(gòu)造函數(shù)的語法如下:

// message: 可選,錯(cuò)誤描述。
// name: 可選,錯(cuò)誤名稱。常量,具體值可以在這里找到:https://developer.mozilla.org/zh-CN/docs/Web/API/DOMException

new DOMException([message[, name]]);

DOMException有以下三個(gè)屬性:

DOMException.code:錯(cuò)誤編號(hào)。

DOMException.message:錯(cuò)誤描述。

DOMException.name:錯(cuò)誤名稱。

以上面那段錯(cuò)誤代碼為例,其拋出的DOMException各屬性的值為:

code: 8
message: "Failed to execute "insertBefore" on "Node": The node before which the new node is to be inserted is not a child of this node."
name: "NotFoundError"
Promise產(chǎn)生的異常

Promise中,如果Promisereject了,就會(huì)拋出異常:PromiseRejectionEvent。注意,下面兩種情況都會(huì)導(dǎo)致Promisereject

業(yè)務(wù)代碼本身調(diào)用了Promise.reject

Promise中的代碼出錯(cuò)。

PromiseRejectionEvent的構(gòu)造函數(shù)目前在瀏覽器中大多都不兼容,這里就不說了。

PromiseRejectionEvent的屬性有兩個(gè):

PromiseRejectionEvent.promise:被rejectPromise

PromiseRejectionEvent.reasonPromisereject的原因。會(huì)傳遞給rejectPromsiecatch中的參數(shù)。

加載資源出錯(cuò)

由于網(wǎng)絡(luò),安全等原因,網(wǎng)頁加載資源失敗,請(qǐng)求接口出錯(cuò)等,也是一種常見的錯(cuò)誤。

關(guān)于錯(cuò)誤的小結(jié)

一個(gè)網(wǎng)頁在運(yùn)行過程中,可能發(fā)生四種錯(cuò)誤:

JavaScript在運(yùn)行過程,語言自身拋出的異常。

JavaScript在運(yùn)行過程中,調(diào)用Web Api時(shí)發(fā)生異常。

Promise中的拒絕。

網(wǎng)頁加載資源,調(diào)用接口時(shí)發(fā)生異常。

我認(rèn)為,對(duì)于前兩種錯(cuò)誤,我們?cè)谄綍r(shí)的開發(fā)過程中,不用特別去區(qū)分,可以統(tǒng)一成:【代碼出錯(cuò)】。

捕獲錯(cuò)誤

網(wǎng)頁發(fā)生錯(cuò)誤,開發(fā)者如何捕獲這些錯(cuò)誤呢 ? 常見的有以下方法。

try...catch...

try...catch…大家都不陌生了。一般用來在具體的代碼邏輯中捕獲錯(cuò)誤。

try {
  throw new Error("oops");
}
catch (ex) {
  console.log("error", ex.message); // error oops
}

當(dāng)try-block中的代碼發(fā)生異常時(shí),可以在catck-block中將異常接住,瀏覽器便不會(huì)拋出錯(cuò)誤。但是,這種方式并不能捕獲異步代碼中的錯(cuò)誤,如:

try {
    setTimeout(function(){
        throw new Error("lala");
    },0);
} catch(e) {
    console.log("error", e.message);
}

這個(gè)時(shí)候,瀏覽器依然會(huì)拋出錯(cuò)誤:Uncaught Error: lala

試想以下,如果我們將所有的代碼合理的劃分,然后都用try catch包起來,是不是就可以捕獲到所有的錯(cuò)誤了呢?可以通過編譯工具來實(shí)現(xiàn)這個(gè)功能。不過,try catch是比較耗費(fèi)性能的。

window.onerror
window.onerror = function(message, source, lineno, colno, error) { ... }

函數(shù)參數(shù):

message:錯(cuò)誤信息(字符串)

source:發(fā)生錯(cuò)誤的腳本URL(字符串)

lineno:發(fā)生錯(cuò)誤的行號(hào)(數(shù)字)

colno:發(fā)生錯(cuò)誤的列號(hào)(數(shù)字)

error:Error對(duì)象(對(duì)象)

注意,如果這個(gè)函數(shù)返回true,那么將會(huì)阻止執(zhí)行瀏覽器默認(rèn)的錯(cuò)誤處理函數(shù)。

window.addEventListener("error")
window.addEventListener("error", function(event) { ... })

我們調(diào)用Object.prototype.toString.call(event),返回的是[object ErrorEvent]。可以看到eventErrorEvent對(duì)象的實(shí)例。ErrorEvent是事件對(duì)象在腳本發(fā)生錯(cuò)誤時(shí)產(chǎn)生,從Event繼承而來。由于是事件,自然可以拿到target屬性。ErrorEvent還包括了錯(cuò)誤發(fā)生時(shí)的信息。

ErrorEvent.prototype.message: 字符串,包含了所發(fā)生錯(cuò)誤的描述信息。

ErrorEvent.prototype.filename: 字符串,包含了發(fā)生錯(cuò)誤的腳本文件的文件名。

ErrorEvent.prototype.lineno: 數(shù)字,包含了錯(cuò)誤發(fā)生時(shí)所在的行號(hào)。

ErrorEvent.prototype.colno: 數(shù)字,包含了錯(cuò)誤發(fā)生時(shí)所在的列號(hào)。

ErrorEvent.prototype.error: 發(fā)生錯(cuò)誤時(shí)所拋出的 Error 對(duì)象。

注意,這里的ErrorEvent.prototype.error對(duì)應(yīng)的Error對(duì)象,就是上文提到的Error, InternalErrorRangeErrorEvalErrorReferenceErrorSyntaxErrorTypeErrorURIErrorDOMException中的一種。

window.addEventListener("unhandledrejection")
window.addEventListener("unhandledrejection", function (event) { ... });

在使用Promise的時(shí)候,如果沒有聲明catch代碼塊,Promise的異常會(huì)被拋出。只能通過這個(gè)方法或者window.onunhandledrejection才能捕獲到該異常。

event就是上文提到的PromiseRejectionEvent。我們只需要關(guān)注其reason就行。

window.onerror 和 window.addEventListener("error")的區(qū)別

首先是事件監(jiān)聽器事件處理器的區(qū)別。監(jiān)聽器只能聲明一次,后續(xù)的聲明會(huì)覆蓋之前的聲明。而事件處理器則可以綁定多個(gè)回調(diào)函數(shù)。

資源(

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/100603.html

相關(guān)文章

  • 前端異常監(jiān)控-看這篇就夠了

    摘要:前端異常監(jiān)控如果是移除的流程,那么編程就一定是將放進(jìn)去的流程。過濾掉運(yùn)行時(shí)錯(cuò)誤上報(bào)加載錯(cuò)誤事件捕獲異常最新的規(guī)范中定義了事件用于全局捕獲對(duì)象沒有處理器時(shí)異常情況。 前端異常監(jiān)控 如果debug是移除bug的流程,那么編程就一定是將bug放進(jìn)去的流程。如果沒有用戶反饋問題,那就代表我們的產(chǎn)品棒棒噠,對(duì)不對(duì)? 主要內(nèi)容 Web規(guī)范中相關(guān)前端異常 異常按照捕獲方式分類 異常的捕獲方式 日志...

    Aklman 評(píng)論0 收藏0
  • 詳解JS錯(cuò)誤處理:前端JS/Vue/React/Iframe/跨域/Node

    摘要:錯(cuò)誤上報(bào)機(jī)制發(fā)送數(shù)據(jù)因?yàn)檎?qǐng)求本身也有可能會(huì)發(fā)生異常,而且有可能會(huì)引發(fā)跨域問題,一般情況下更推薦使用動(dòng)態(tài)創(chuàng)建標(biāo)簽的形式進(jìn)行上報(bào)。 js錯(cuò)誤捕獲 js錯(cuò)誤的實(shí)質(zhì),也是發(fā)出一個(gè)事件,處理他 error實(shí)例對(duì)象 對(duì)象屬性 message:錯(cuò)誤提示信息 name:錯(cuò)誤名稱(非標(biāo)準(zhǔn)屬性)宿主環(huán)境賦予 stack:錯(cuò)誤的堆棧(非標(biāo)準(zhǔn)屬性)宿主環(huán)境賦予 對(duì)象類型(7種) Synt...

    張利勇 評(píng)論0 收藏0
  • 前端魔法堂——異常不僅僅是try/catch

    摘要:我打算分成前端魔法堂異常不僅僅是和前端魔法堂調(diào)用棧,異常實(shí)例中的寶藏兩篇分別敘述內(nèi)置自定義異常類,捕獲運(yùn)行時(shí)異常語法異常網(wǎng)絡(luò)請(qǐng)求異常事件,什么是調(diào)用棧和如何獲取調(diào)用棧的相關(guān)信息。 前言 ?編程時(shí)我們往往拿到的是業(yè)務(wù)流程正確的業(yè)務(wù)說明文檔或規(guī)范,但實(shí)際開發(fā)中卻布滿荊棘和例外情況,而這些例外中包含業(yè)務(wù)用例的例外,也包含技術(shù)上的例外。對(duì)于業(yè)務(wù)用例的例外我們別無它法,必須要求實(shí)施人員與用戶共同...

    bladefury 評(píng)論0 收藏0
  • 前端性能與異常上報(bào)

    摘要:回過頭來發(fā)現(xiàn),我們的項(xiàng)目,雖然在服務(wù)端層面做好了日志和性能統(tǒng)計(jì),但在前端對(duì)異常的監(jiān)控和性能的統(tǒng)計(jì)。對(duì)于前端的性能與異常上報(bào)的可行性探索是有必要的。這是我們頁面加載性能優(yōu)化需求中主要上報(bào)的相關(guān)信息。 概述 對(duì)于后臺(tái)開發(fā)來說,記錄日志是一種非常常見的開發(fā)習(xí)慣,通常我們會(huì)使用try...catch代碼塊來主動(dòng)捕獲錯(cuò)誤、對(duì)于每次接口調(diào)用,也會(huì)記錄下每次接口調(diào)用的時(shí)間消耗,以便我們監(jiān)控服務(wù)器接口...

    gggggggbong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<