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

資訊專欄INFORMATION COLUMN

JavaScript 中的錯(cuò)誤處理機(jī)制

AbnerMing / 687人閱讀

摘要:錯(cuò)誤處理在開發(fā)和調(diào)試過程中都顯得尤為重要。跟全局函數(shù)有關(guān)的錯(cuò)誤,在之后已經(jīng)不再出現(xiàn)了內(nèi)部錯(cuò)誤。由引擎拋出的錯(cuò)誤范圍錯(cuò)誤。事件任何沒有的錯(cuò)誤都會(huì)觸發(fā)對象的事件。事件可以接收三個(gè)參數(shù)錯(cuò)誤消息錯(cuò)誤所在的和行號。

錯(cuò)誤處理在開發(fā)和調(diào)試過程中都顯得尤為重要。有些沒有進(jìn)行錯(cuò)誤處理的應(yīng)用,直接就將瀏覽器的錯(cuò)誤展示給了用戶,極大的降低了用戶體驗(yàn)。比如有些很 low 的網(wǎng)站,打開某些頁面就直接彈出 "object" 這樣的錯(cuò)誤,用戶看到之后一臉懵逼,心想這是什么鬼?讓人感覺極其的不專業(yè)??梢婂e(cuò)誤處理對一個(gè)應(yīng)用來說是多么的重要。

這篇文章主要是給大家科普一些關(guān)于錯(cuò)誤處理的知識(shí),讓大家在腦海中有一個(gè)概覽。下一篇文章中我會(huì)結(jié)合具體的項(xiàng)目以及當(dāng)前主流的一些框架,比如react, redux,來更深入的介紹如何運(yùn)用這些框架去封裝一整套錯(cuò)誤處理的解決方案。

error 對象

Error 構(gòu)造對象可以實(shí)例化一個(gè) error 對象 (也就是Error 實(shí)例),而 error 對象就是一個(gè)包含了錯(cuò)誤信息的對象。當(dāng)代碼解析或者運(yùn)行時(shí)發(fā)生錯(cuò)誤,javascript 引擎就會(huì)自動(dòng)產(chǎn)生并拋出一個(gè) error 對象, 然后程序就中斷在發(fā)生錯(cuò)誤的地方。

示例:

const error = new Error("Whoop!");
error.message; // Whoop!
error.name; // Error
error.stack; // "Error: Whoops! at :1:13"

我們常用的 messagename 都是 error 的標(biāo)準(zhǔn)屬性,由于各個(gè)瀏覽器廠商對 error 進(jìn)行了不同的擴(kuò)展,所以在不同的瀏覽器中,error 也有不同的屬性和方法, 非標(biāo)準(zhǔn)屬性中我們常用的是 stack 屬性(很多瀏覽器都擴(kuò)展了這一屬性), 它用來表示棧跟蹤信息。

屬性 含義
message 錯(cuò)誤信息
name 錯(cuò)誤類型
constructor 指定一個(gè)函數(shù)用來創(chuàng)建實(shí)例的原型,也就是指定構(gòu)造器(創(chuàng)建自定義 Error 會(huì)用到)
stack (非標(biāo)準(zhǔn)) 棧跟蹤信息
error 類型

除了普通的 Error 構(gòu)造對象以外, javascript 還實(shí)現(xiàn)了其他幾種主要的 error 構(gòu)造對象1.

類型 解析 實(shí)例
EvalError eval錯(cuò)誤。跟全局函數(shù) eval() 有關(guān)的錯(cuò)誤,在 ES5 之后已經(jīng)不再出現(xiàn)了
InternalError 內(nèi)部錯(cuò)誤。由 JavaScript 引擎拋出的錯(cuò)誤
RangeError 范圍錯(cuò)誤。發(fā)生在一個(gè)數(shù)值或參數(shù)超出其合法范圍,主要包括超出數(shù)組范圍或者超出數(shù)字取值范圍 new Array(-1); (1234).toExponential(21);
ReferenceError 引用錯(cuò)誤。通常是由于引用了一個(gè)不存在的值。 a.toString();
SyntaxError 語法錯(cuò)誤。 a ? a+1;
TypeError 類型錯(cuò)誤。通常是因?yàn)樵趫?zhí)行特定的類型操作時(shí),變量的類型不符合要求。例如變量中保存著意外類型,訪問不存在的方法等。 var a = new {}; var a = {a:1}; a.reverse(); // 對象并沒有 reverser 方法
URIError decodeURI() 或者 encodeURI() 傳入非法參數(shù)時(shí),也包括 encodeURIComponent() 和 decodeURIComponent() decodeURI("http://www.test.com&%"); encodeURIComponent("uD800");
encodeURI 和 encodeURIComponent 的區(qū)別

這里順便說一下 encodeURIencodeURIComponent 的區(qū)別。已經(jīng)了解的同學(xué)可以忽略這一小部分,繼續(xù)往前面看。

encodeURI 是對統(tǒng)一資源標(biāo)識(shí)符 (URI) 全部編碼,而 encodeURIComponent 對統(tǒng)一資源標(biāo)識(shí)符 (URI) 部分編碼

假設(shè)一個(gè) URI 是一個(gè)完整的 URI, 那么我們不必對那些在 URI 中保留的并且?guī)в刑厥夂x的字符進(jìn)行編碼。由于 encodeURI 會(huì)替換掉所有字符,但是卻不包含一些保留字符,如 "&", "+", "=" 等(這些字符在 GET 和 POST 請求中是特殊字符,需要被編碼),所以 encodeURI 本身無法產(chǎn)生能使用與 HTTP GET 或者 POST 請求的 URI。但是我們可以使用 encodeURIComponent 來對這些字符進(jìn)行編碼。

encodeURIComponent 轉(zhuǎn)義除了字母、數(shù)字、(、)、.、!、~、*、"、-和_之外的所有字符。
為了避免服務(wù)器收到不可預(yù)知的請求,對任何用戶輸入的作為 URI 部分的內(nèi)容都需要用 encodeURIComponent 進(jìn)行轉(zhuǎn)義。
拋出和捕獲錯(cuò)誤 throw and try...catch

通常使用 throw 語句拋出錯(cuò)誤,并用 try...catch 進(jìn)行捕獲。通常會(huì)把所有可能會(huì)拋出錯(cuò)誤的代碼都放在 try 語句塊中,而把那些用于錯(cuò)誤處理的代碼放在 catch 塊中。

throw 語句

throw 過程是阻塞的,程序會(huì)中斷在第一個(gè)拋出錯(cuò)誤的地方,所以后面的代碼不會(huì)執(zhí)行。

throw new SyntaxError("this is syntax error"); 
throw 123; // 不執(zhí)行
throw "hi there"; // 不執(zhí)行
throw true;  // 不執(zhí)行
catch 語句

catch 代碼塊捕獲錯(cuò)誤之后,程序不會(huì)中斷,會(huì)按照正常流程繼續(xù)執(zhí)行下去。

try {
  throw new Error("Whoops!");
} catch (e) {
  console.log(e.name + ":" + e.message);
}
console.log("hello!");

// Error:Whoops!
// hello!
finally 語句

finallytry...catch 中是可選的,但是一旦使用了它,它里面的代碼就一定會(huì)被執(zhí)行,也就是說不管 try 語句塊中的代碼是否正常執(zhí)行,finnaly 都會(huì)被執(zhí)行。正如下面的代碼, 即使在 try 中資源被阻塞,由于我們在 finnaly 中執(zhí)行了關(guān)閉操作,文件最后還是會(huì)被關(guān)閉。

openMyFile()
try {
   // 阻塞資源
   writeMyFile(theData);
} finally {
   closeMyFile(); // 始終會(huì)關(guān)閉資源
}

處理一個(gè)特定的錯(cuò)誤。

    try {
      foo.bar();
    } catch (e) {
      switch (e.name) {
        case "RangeError":
          //do something
          console.log("RangeError: " + e.message);
          break;
        case "ReferenceError":
          //do something
          console.log("ReferenceError: " + e.message);
          break;
        default:
          console.log(e.name + ":" + e.message);
      }
    }
error 事件
任何沒有 catch 的錯(cuò)誤都會(huì)觸發(fā) window 對象的 error 事件。

error 事件可以接收三個(gè)參數(shù):錯(cuò)誤消息、錯(cuò)誤所在的 URL 和行號。你可以通過以下兩種方式給 window 綁上 error 事件2。

  // message: 錯(cuò)誤消息, source: 發(fā)生錯(cuò)誤文件的 URL, lineno: 錯(cuò)誤行號

  // 方法一
  window.onerror = function(messageOrEvent, source, lineno, colno, error) {
    alert(messageOrEvent, source, lineno, colno, error);
  }
  
  or 
  
  window.onerror = console.log;
  throw new Error("whoops!");
  
  // 方法二 
  window.addEventListener("error", function(errorEvent){
      alert(errorEvent.error);
  });

在實(shí)際情況中,error 事件并不常用(但是在某些情況下,如微信端的調(diào)試,error 事件還是挺有用的),因?yàn)槲覀冞€是希望所有的異常都能得到很好的處理,而不是把錯(cuò)誤交給瀏覽器。但有的時(shí)候并不是所有的錯(cuò)誤都能夠被撲獲,并且某些業(yè)務(wù)場景會(huì)使用到追蹤瀏覽器報(bào)錯(cuò)的工具,這時(shí)候可能就需要將瀏覽器的錯(cuò)誤拋出去,所以在這種情況下也需要去全局監(jiān)聽 error 事件。

自定義錯(cuò)誤類型 Custom Error Types

創(chuàng)建一個(gè)自定義類 CustomError, 以方便去擴(kuò)展更多的自定義 Error

CustomError.js

class CustomError extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    if (typeof Error.captureStackTrace === "function") {
      // 在瀏覽器領(lǐng)域,除了使用V8引擎的 Chrome,
      // 其它瀏覽器中不存在 Error.captureStackTrace()這一接口,
      // 所以在這里做一個(gè)條件判斷。
      Error.captureStackTrace(this, this.constructor); // 返回調(diào)用堆棧信息, 用于在 error 對象上添加合理的 stack 屬性。
    } else {
      this.stack = new Error(message).stack;
    }
  }
}
Error.captureStackTrace

Error.captureStackTrace 是用來在 targetObject 中添加一個(gè) .stack 屬性。對該屬性進(jìn)行訪問時(shí),將以字符串的形式返回 Error.captureStackTrace() 語句被調(diào)用時(shí)的代碼位置信息(即:調(diào)用棧歷史)。

Error.captureStackTrace(targetObject[, constructorOpt])

除了 targetObject, captureStackTrace 還接受一個(gè)類型為 function 的可選參數(shù) constructorOpt,當(dāng)傳遞該參數(shù)時(shí),調(diào)用棧中所有 constructorOpt 函數(shù)之上的信息(包括 constructorOpt 函數(shù)自身),都會(huì)在訪問 targetObject.stack 時(shí)被忽略。當(dāng)需要對終端用戶隱藏內(nèi)部的技術(shù)細(xì)節(jié)時(shí), constructorOpt 參數(shù)會(huì)很有用。

擴(kuò)展自定義 Error 類型

通過基類 CustomError,我們可以創(chuàng)建出更多的自定義 Error, 比如下面的 HttpRequestErrorLoginExpiredError

HttpRequestError.js

class HttpRequestError extends CustomError {
  constructor(message, requestId, code, httpStatusCode) {
    const defaultAPIErrorMessage = () => {
      // 檢查是否有網(wǎng)
      return window.navigator.onLine ? "Something wrong" : "No connection";
    };

    message = message || defaultAPIErrorMessage();
    super(message);

    this.requestId = requestId;
    this.code = code;
    this.httpStatusCode = httpStatusCode;
  }
}

throw new HttpRequestError(null, "requestId", "code", "httpStatusCode");

LoginExpiredError.js

class LoginExpiredError extends CustomError {
  constructor(message) {
    message = message || "Your session has expired!";

    super(message);
  }
}

throw new LoginExpiredError();

當(dāng)我們創(chuàng)建了各種自定義 Error 之后,我們可以在不同的場景去使用它們了,比如在 http 請求失敗的時(shí)候拋出 HttpRequestError,并彈出對話框提示用戶。在用戶登錄過期之后,拋出 LoginExpiredError,彈出對話框,并自動(dòng) logout 等等。通過拋出不同的 Error 類型,才能讓我們進(jìn)行不同的撲獲處理。

  const deffer = Q.deffer();

  if (expired) {
    deffer.reject(new LoginExpiredError()); // 通過 promise 拋出異常
  }

  if (error instanceof LoginExpiredError) { // 撲獲異常
    logout();
  }
結(jié)尾

關(guān)于 Error 的介紹就先講到這里。

  • Error in MDN ?

  • window.onerror ?

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

    轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/88005.html

    相關(guān)文章

    • JS筆記

      摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

      rottengeek 評論0 收藏0
    • 精讀《你不知道的javascript(中卷)》

      摘要:強(qiáng)制類型轉(zhuǎn)換本章介紹了的數(shù)據(jù)類型之間的轉(zhuǎn)換即強(qiáng)制類型轉(zhuǎn)換包括顯式和隱式。強(qiáng)制類型轉(zhuǎn)換常常為人詬病但實(shí)際上很多時(shí)候它們是非常有用的。隱式強(qiáng)制類型轉(zhuǎn)換則沒有那么明顯是其他操作的副作用。在處理強(qiáng)制類型轉(zhuǎn)換的時(shí)候要十分小心尤其是隱式強(qiáng)制類型轉(zhuǎn)換。 前言 《你不知道的 javascript》是一個(gè)前端學(xué)習(xí)必讀的系列,讓不求甚解的JavaScript開發(fā)者迎難而上,深入語言內(nèi)部,弄清楚JavaSc...

      李世贊 評論0 收藏0
    • Vue.js@2.6.10更新內(nèi)置錯(cuò)誤機(jī)制,F(xiàn)undebug同步支持相應(yīng)錯(cuò)誤監(jiān)控

      摘要:摘要的錯(cuò)誤監(jiān)控插件同步支持異步錯(cuò)誤監(jiān)控。此次更新,我們對的監(jiān)控插件做了相應(yīng)的更新,來更好地支持使用框架開發(fā)的應(yīng)用錯(cuò)誤的監(jiān)控。程序運(yùn)行后,成功捕獲該錯(cuò)誤總結(jié)更新到,對錯(cuò)誤處理提供了更加強(qiáng)大的支持。 摘要: Fundebug 的 JavaScript 錯(cuò)誤監(jiān)控插件同步支持 Vue.js 異步錯(cuò)誤監(jiān)控。 Vue.js 從誕生至今已經(jīng) 5 年,尤大在今年 2 月份發(fā)布了重大更新,即Vue 2....

      DC_er 評論0 收藏0
    • JavaScript工作機(jī)制:第1部分

      摘要:工作機(jī)制第部分本文轉(zhuǎn)載自眾成翻譯譯者網(wǎng)絡(luò)埋伏紀(jì)事鏈接原文隨著越來越受歡迎,開發(fā)團(tuán)隊(duì)正在將其用在技術(shù)棧的各個(gè)方面,包括前端后端混合應(yīng)用嵌入式設(shè)備等等。之后,步驟將是如下這樣調(diào)用棧中的每個(gè)條目稱為棧幀。 JavaScript工作機(jī)制:第1部分 本文轉(zhuǎn)載自:眾成翻譯譯者:網(wǎng)絡(luò)埋伏紀(jì)事鏈接:http://www.zcfy.cc/article/3965原文:https://blog.sessi...

      xiaodao 評論0 收藏0
    • JavaScripr中常遇到的錯(cuò)誤和this關(guān)鍵字

      摘要:通過使用提供的異常處理語句,可以用結(jié)構(gòu)化的方式來捕捉發(fā)生的錯(cuò)誤,讓異常處理帶啊與核心業(yè)務(wù)代碼實(shí)現(xiàn)分離。錯(cuò)誤與異常處理在應(yīng)用中的重要性是毋庸置疑的。包括內(nèi)置對象函數(shù)在內(nèi)的所有函數(shù)都可以用來調(diào)用,這種函數(shù)調(diào)用被稱為構(gòu)造函數(shù)調(diào)用。 錯(cuò)誤與異常 概念 錯(cuò)誤與異常是什么錯(cuò)誤,指程序中的費(fèi)正常運(yùn)行狀態(tài),在其他編程語言中稱為‘異常’或‘錯(cuò)誤’。解釋器會(huì)為每一個(gè)錯(cuò)誤創(chuàng)建并拋出一個(gè)Error對象,其中包...

      klinson 評論0 收藏0

    發(fā)表評論

    0條評論

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