成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

翻譯-JavaScript異常和調(diào)用堆棧的處理

adam1q84 / 2114人閱讀

摘要:調(diào)用堆棧實(shí)際上就是一個(gè)方法列表,按調(diào)用順序保存所有在運(yùn)行期被調(diào)用的方法。調(diào)用堆棧會(huì)將當(dāng)前正在執(zhí)行的函數(shù)調(diào)用壓入堆棧,一旦函數(shù)調(diào)用結(jié)束,又會(huì)將它移出堆棧。

原文

JavaScript Errors and Stack Traces in Depth

調(diào)用棧Call Stack是如何工作的

棧是一個(gè)后進(jìn)先出LIFO (Last in,F(xiàn)irst out)的數(shù)據(jù)結(jié)構(gòu)。調(diào)用堆棧實(shí)際上就是一個(gè)方法列表,按調(diào)用順序保存所有在運(yùn)行期被調(diào)用的方法。調(diào)用堆棧會(huì)將當(dāng)前正在執(zhí)行的函數(shù)調(diào)用壓入堆棧,一旦函數(shù)調(diào)用結(jié)束,又會(huì)將它移出堆棧。

console.trace()編寫一個(gè)簡(jiǎn)單的例子來演示一下

function c() {
    console.log("c");
    console.trace();
}
function b() {
    console.log("b");
    c();
}
function a() {
    console.log("a");
    b();
}
a();

我們可以看到console輸出的結(jié)果

console.trace
c @ VM59:3
b @ VM59:7
a @ VM59:11
(anonymous) @ VM59:13

我們調(diào)用console.trace()是在c方法里,這個(gè)時(shí)候c還在執(zhí)行,并沒有返回,因此從console就能看到調(diào)用堆棧頂就是c。我們可以稍微改變一下,比如把console.trace()放在b方法里調(diào)用,如下:

function c() {
    console.log("c");
}
function b() {
    console.log("b");
    c();
    console.trace();
}
function a() {
    console.log("a");
    b();
}
a();

這時(shí)候我們?cè)儆^察console,就看不到c方法了

VM61:8 console.trace
b @ VM61:8
a @ VM61:13
(anonymous) @ VM61:16

因?yàn)?b>console.trace()的調(diào)用是發(fā)生在了c調(diào)用之后,因此這個(gè)時(shí)候,棧頂c的幀已經(jīng)出棧,自然就看不到了。

Error對(duì)象以及異常處理

通常程序有異常的時(shí)候都會(huì)有一個(gè)Error對(duì)象拋出。Error.prototype有以下幾種標(biāo)準(zhǔn)屬性:

constructor

message

name

更多的,可以翻翻MDN的文檔。其中有一個(gè)stack屬性,要重點(diǎn)關(guān)注。盡管這是一個(gè)非標(biāo)準(zhǔn)屬性,但是絕大多數(shù)瀏覽器都支持這個(gè)屬性。

一般我們使用try/catch來捕獲異常,同時(shí),我們還可以使用finally來做一些清理的工作,因?yàn)?b>finally里的代碼是一定會(huì)執(zhí)行的。

try {
    console.log("The try block is running...");
} finally {
    try {
        throw new Error("Error inside finally.");
    } catch (err) {
        console.log("Caught an error inside the finally block.");
    }
}

有一個(gè)值得探討的地方,那就是,你可以throw任何數(shù)據(jù)而不僅僅是一個(gè)Error類的實(shí)例

function runWithoutThrowing(func) {
    try {
        func();
    } catch (e) {
        console.log("There was an error, but I will not throw it.");
        console.log("The error"s message was: " + e.message)
    }
}
function funcThatThrowsString() {
    throw "I am a String.";
}
runWithoutThrowing(funcThatThrowsString);

這種情況下,e.message的值一定就是undefined了,因?yàn)槟銙伋龅牟⒉皇且粋€(gè)Error類的實(shí)例。

異常還可以作為第一個(gè)參數(shù)傳給callback函數(shù)。舉個(gè)fs.readdir的例子,

const fs = require("fs");
fs.readdir("/example/i-do-not-exist", function callback(err, dirs) {
    if (err instanceof Error) {
        // `readdir` will throw an error because that directory does not exist
        // We will now be able to use the error object passed by it in our callback function
        console.log("Error Message: " + err.message);
        console.log("See? We can use Errors without using try statements.");
    } else {
        console.log(dirs);
    }
});
處理調(diào)用堆棧

思路就兩種:

Error.captureStackTrace(NodeJS)

Error.prototype.stack

Error.captureStackTrace是NodeJS提供的一個(gè)方法,這個(gè)方法會(huì)捕捉當(dāng)前的調(diào)用堆棧,然后保存到你指定的對(duì)象。

const myObj = {};
function c() {
}
function b() {
    // Here we will store the current stack trace into myObj
    Error.captureStackTrace(myObj);
    c();
}
function a() {
    b();
}
// First we will call these functions
a();
// Now let"s see what is the stack trace stored into myObj.stack
console.log(myObj.stack);

另外一種就是利用Error對(duì)象的stack屬性。但里有個(gè)問題,就是你不知道在try/catch里拋出的是什么樣的值,這個(gè)值它不一定是Error類的實(shí)例。不過我們依然能夠處理,而且是非常巧妙的進(jìn)行處理。比如看看Chai這個(gè)斷言庫(kù)的AssertionError類的構(gòu)造函數(shù)。

// `ssfi` stands for "start stack function". It is the reference to the
// starting point for removing irrelevant frames from the stack trace
function AssertionError (message, _props, ssf) {
  var extend = exclude("name", "message", "stack", "constructor", "toJSON")
    , props = extend(_props || {});
  // Default values
  this.message = message || "Unspecified AssertionError";
  this.showDiff = false;
  // Copy from properties
  for (var key in props) {
    this[key] = props[key];
  }
  // Here is what is relevant for us:
  // If a start stack function was provided we capture the current stack trace and pass
  // it to the `captureStackTrace` function so we can remove frames that come after it
  ssf = ssf || arguments.callee;
  if (ssf && Error.captureStackTrace) {
    Error.captureStackTrace(this, ssf);
  } else {
    // If no start stack function was provided we just use the original stack property
    try {
      throw new Error();
    } catch(e) {
      this.stack = e.stack;
    }
  }
}
參考文檔

arguments.callee

arguments.caller

Error

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

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

相關(guān)文章

  • JavaScript 編程精解 中文第三版 八、Bug 錯(cuò)誤

    摘要:幸運(yùn)的是,使用符號(hào)創(chuàng)建的構(gòu)造器,如果在不使用來調(diào)用,則始終會(huì)報(bào)錯(cuò),即使在非嚴(yán)格模式下也不會(huì)產(chǎn)生問題。 來源:ApacheCN『JavaScript 編程精解 中文第三版』翻譯項(xiàng)目原文:Bugs and Errors 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 自豪地采用谷歌翻譯 部分參考了《JavaScript 編程精解(第 2 版)》 調(diào)試的難度是開始編寫代碼的兩倍。 因此,如...

    wujl596 評(píng)論0 收藏0
  • JavaScript如何工作:引擎,運(yùn)行時(shí)調(diào)用堆棧概述

    摘要:如果我們進(jìn)入一個(gè)函數(shù),我們?cè)诙褩5捻敳?。看看下面的代碼當(dāng)引擎開始執(zhí)行此代碼時(shí),調(diào)用堆棧將為空。之后,步驟如下調(diào)用堆棧中的每個(gè)條目稱為堆棧幀。這正是拋出異常時(shí)構(gòu)造堆棧跟蹤的方式當(dāng)異常發(fā)生時(shí),它基本上是調(diào)用堆棧的狀態(tài)。 隨著JavaScript越來越受歡迎,團(tuán)隊(duì)正在利用這個(gè)技術(shù)棧在多個(gè)層次- 前端,后端,混合應(yīng)用程序,嵌入式設(shè)備等等提供支持。 這篇文章旨在成為系列中第一個(gè)旨在深入挖掘Jav...

    wwolf 評(píng)論0 收藏0
  • javasctipt 工作原理之調(diào)用

    摘要:譯者注翻譯一個(gè)對(duì)新手比較友好的工作原理解析系列文章注意以下全部是概念經(jīng)驗(yàn)豐富的老鳥可以離場(chǎng)啦正文從這里開始隨著的流行團(tuán)隊(duì)們正在利用來支持多個(gè)級(jí)別的技術(shù)棧包括前端后端混合開發(fā)嵌入式設(shè)備以及更多這篇文章旨在成為深入挖掘和實(shí)際上他是怎么工作的系列 譯者注 翻譯一個(gè)對(duì)新手比較友好的 JavaScript 工作原理解析系列文章 注意: 以下全部是概念,經(jīng)驗(yàn)豐富的老鳥可以離場(chǎng)啦 正文從這里開始 隨...

    Pines_Cheng 評(píng)論0 收藏0
  • 翻譯連載 | 第 9 章:遞歸(下)-《JavaScript輕量級(jí)函數(shù)式編程》 |《你不知道JS》

    摘要:每個(gè)函數(shù)調(diào)用都將開辟出一小塊稱為堆棧幀的內(nèi)存。當(dāng)?shù)诙€(gè)函數(shù)開始執(zhí)行,堆棧幀增加到個(gè)。當(dāng)這個(gè)函數(shù)調(diào)用結(jié)束后,它的幀會(huì)從堆棧中退出。保持堆棧幀跟蹤函數(shù)調(diào)用的狀態(tài),并將其分派給下一個(gè)遞歸調(diào)用迭。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關(guān)于譯者:這是一個(gè)流淌著滬江血液的純粹工程:認(rèn)真,是 HTM...

    LeviDing 評(píng)論0 收藏0
  • JavaScript中錯(cuò)誤正確處理方式,你用對(duì)了嗎?

    摘要:?jiǎn)卧獪y(cè)試會(huì)體現(xiàn)出以上錯(cuò)誤處理程序的作用如果出現(xiàn)問題,錯(cuò)誤處理程序就會(huì)返回。同時(shí)錯(cuò)誤會(huì)展開堆棧,這對(duì)調(diào)試非常有幫助。展開堆棧處理異常的一種方式是在調(diào)用堆棧的頂部加入。確保你的錯(cuò)誤處理處在相同域中,這樣會(huì)保留原始消息,堆棧和自定義錯(cuò)誤對(duì)象。 JavaScript的事件驅(qū)動(dòng)范式增添了豐富的語(yǔ)言,也是讓使用JavaScript編程變得更加多樣化。如果將瀏覽器設(shè)想為JavaScript的事件驅(qū)動(dòng)...

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

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

0條評(píng)論

閱讀需要支付1元查看
<