最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡單了解TypeScript中如何繼承 Error 類

 更新時(shí)間:2019年06月21日 17:03:56   作者:Harttle  
這篇文章主要介紹了簡單了解TypeScript中如何繼承 Error 類,一個(gè)典型的網(wǎng)站服務(wù)器可能需要有 NetworkError, DatabaseError, UnauthorizedError 等。 我們希望這些類都擁有 Error 的特性:有錯(cuò)誤消息、有調(diào)用棧、有方便打印的 toString 等。,需要的朋友可以參考下

前言

在JavaScript 中很多時(shí)候都需要自定義錯(cuò)誤,尤其是開發(fā) Node.js 應(yīng)用的時(shí)候。 比如一個(gè)典型的網(wǎng)站服務(wù)器可能需要有 NetworkError, DatabaseError, UnauthorizedError 等。 我們希望這些類都擁有 Error 的特性:有錯(cuò)誤消息、有調(diào)用棧、有方便打印的 toString 等。 最直觀的實(shí)現(xiàn)方式便是 繼承 Error 類。 但考慮 TypeScript 需要編譯到 ES5 兼容性問題會較為復(fù)雜, 本文用來幫助理解 TypeScript 中繼承 Error 的問題來源以及對應(yīng)的幾種解決方式。

我們需要怎樣的 CustomError

為了容易討論最佳實(shí)踐,首先明確我們自定義的 CustomError 需要做到哪些功能。 下面是 Harttle 的觀點(diǎn):

  1. 可以調(diào)用 new CustomError() 來創(chuàng)建,并且 instanceof Error 操作應(yīng)該返回 true??梢杂脕韯?chuàng)建是基本要求,能夠被視為 Error 的實(shí)例能夠兼容既有系統(tǒng)(比如 toString() 要返回調(diào)用棧),同時(shí)符合慣例。
  2. .stack 屬性首行應(yīng)為 CustomeError: <message>。如果是 Error: <message> 可能就沒那么漂亮。
  3. .stack 屬性應(yīng)當(dāng)包含調(diào)用棧并指向 new CustomError() 的那一行。這一點(diǎn)可能是關(guān)鍵,如果指向 CustomError 構(gòu)造函數(shù)中的某一行,就會給這個(gè)類的使用方造成困惑。

下面舉個(gè)例子,這是一個(gè) message 為 "intended" 的 CustomError 的 .stack 屬性值:

CustomError: intended
at Object.<anonymous> (/Users/harttle/Downloads/bar/a.js:10:13)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:694:10)
at startup (bootstrap_node.js:204:16)
at bootstrap_node.js:625:3

ES5 中如何繼承 Error?

Error 是一個(gè)特殊的對象,或者說 JavaScript 的 new 是一個(gè)奇葩的存在。 為方便后續(xù)討論,我們先討論組 ES5 時(shí)代是怎樣繼承 Error 的。 我們說 JavaScript 是一門混雜的語言,如何繼承 Error 就是一個(gè)典型的例子。 如果你熟悉 原型繼承的方式,應(yīng)該會寫出如下代碼:

function CustomError (message) {
Error.call(this, message)
}
CustomError.prototype = new Error()

因?yàn)?stack 只在 new 的時(shí)候生成,上述實(shí)現(xiàn)不能滿足功能 2 和功能 3,也就是說:

  • stack 的第一行是總是 Error 而不是 CustomError 且不包含 message 信息。
  • stack 總是指向 new Error() 的那一行,而不是 new CustomError()。

Node 文檔 中描述了一個(gè) captureStackTrace 方法來解決這個(gè)問題,改動后的實(shí)現(xiàn)如下:

function CustomError (msg) {
this.name = 'CustomError'
this.message = msg
Error.captureStackTrace(this, CustomError)
}
CustomError.prototype = new Error()

其中 .captureStackTrace() 會使用傳入對象的 name 和 message 來生成 stack 的前綴;同時(shí)第二個(gè)參數(shù)用來指定在調(diào)用棧中忽略掉哪一部分,這樣棧就會指向 new CustomError 的地方而不是 captureStackTrace() 的地方。

ES6 中如何繼承 Error?

既然 ES6 通過 class 和 extends 等關(guān)鍵字給出了類繼承機(jī)制, 那么想必通過編寫 CustomError 類來繼承 Error。事實(shí)也確實(shí)如此,只需要在構(gòu)造函數(shù)中調(diào)用父類構(gòu)造函數(shù)并賦值 name 即可實(shí)現(xiàn)文章開始提到的三個(gè)功能:

class CustomError extends Error {
constructor(msg) {
super(msg)
this.name = 'CustomError'
}
}

TypeScript 中如何繼承 Error?

ES6 中提供了 new.target 屬性, 使得 Error 的構(gòu)造函數(shù)中可以獲取 CustomError 的信息,以完成原型鏈的調(diào)整。 因此 TypeScript 需要編譯到 ES5 時(shí)上述功能仍然是無法自動實(shí)現(xiàn)。 在 TypeScript 中的體現(xiàn)是形如上述 ES6 的代碼片段會被編譯成:

var CustomError = /** @class */ (function (_super) {
__extends(CustomError, _super);
function CustomError(msg) {
var _this = _super.call(this, msg) || this;
_this.name = 'CustomError';
return _this;
}
return CustomError;
}(Error));

注意 var _this = _super.call(this, msg) || this; 中 this 被替換掉了。 在 TypeScript 2.1 的 changelog 中描述了這個(gè) Breaking Change。 **這會造成 CustomError 的所有對象方法都無法使用,這里介紹幾種 workaround:

題外話,這個(gè)分支可能會導(dǎo)致測試覆蓋率中的 分支未覆蓋問題??梢灾辉?ES6 下產(chǎn)生測試覆蓋報(bào)告來解決。

1. 使用 setPrototypeOf 還原原型鏈

這是 TypeScript 官方給出的解決方法,見這里。

class CustomError extends Error {
constructor(message) {
super(message);
Object.setPrototypeOf(this, FooError.prototype);
}
}

注意這是一個(gè)性能很差的方法,且在 ES6 中提出,兼容性也很差。在不兼容的環(huán)境下可以使用 __proto__ 來替代。

2. 堅(jiān)持使用 ES5 的方式

不使用 ES6 特性,仍然使用本文前面介紹的 『ES5 中如何繼承 Error?』給出的方法。

3. 限制對象方法的使用

雖然 CustomError 的對象函數(shù)無法使用,但 CustomError 仍然支持 protected 級別的方法供子類使用,閹割的地方在于自己不能調(diào)用。 由于 JavaScript 中對象屬性必須在構(gòu)造函數(shù)內(nèi)賦值,因此對象屬性也不會受到影響。也就是說:

class CustomError extends Error {
count: number = 0
constructor(msg) {
super(msg)
this.count // OK,屬性不受影響
this.print() // TypeError: _this.print is not a function,因?yàn)?this 被替換了
}
print() { 
console.log(this.stack)
}
}
class DerivedError extends CustomError {
constructor(msg) {
super(msg)
super.print() // OK,因?yàn)?print 是直接從父類原型獲取的,即 `_super.prototype.print`
}
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JS判斷是否長按某一鍵的方法

    JS判斷是否長按某一鍵的方法

    這篇文章主要介紹了JS判斷是否長按某一鍵的方法,涉及JavaScript針對鍵盤按鍵的判斷及響應(yīng)操作技巧,需要的朋友可以參考下
    2016-03-03
  • JavaScript數(shù)據(jù)類型檢測代碼分享

    JavaScript數(shù)據(jù)類型檢測代碼分享

    這篇文章主要向大家分享了一段JavaScript實(shí)現(xiàn)數(shù)據(jù)類型檢測的代碼,附上參數(shù)說明和使用說明,希望小伙伴們能夠喜歡
    2015-01-01
  • JS前向后瞻正則表達(dá)式定義與用法示例

    JS前向后瞻正則表達(dá)式定義與用法示例

    這篇文章主要介紹了JS前向后瞻正則表達(dá)式定義與用法,分析了前向后瞻正則表達(dá)式的具體定義、功能及具體使用技巧,需要的朋友可以參考下
    2016-12-12
  • 微信小程序使用request網(wǎng)絡(luò)請求操作實(shí)例

    微信小程序使用request網(wǎng)絡(luò)請求操作實(shí)例

    這篇文章主要介紹了微信小程序使用request網(wǎng)絡(luò)請求操作,結(jié)合實(shí)例形式分析了wx.request(object)網(wǎng)絡(luò)請求操作的具體使用技巧,需要的朋友可以參考下
    2017-12-12
  • 原生js實(shí)現(xiàn)日期聯(lián)動

    原生js實(shí)現(xiàn)日期聯(lián)動

    日期聯(lián)動算是一個(gè)比較常見的功能了,隨便度娘一下,你就能找到N多代碼,今天給大家介紹的是個(gè)人比較常用,代碼很簡潔,高效,這里推擠給大家。
    2015-01-01
  • 微信小程序?qū)崿F(xiàn)點(diǎn)擊按鈕修改view標(biāo)簽背景顏色功能示例【附demo源碼下載】

    微信小程序?qū)崿F(xiàn)點(diǎn)擊按鈕修改view標(biāo)簽背景顏色功能示例【附demo源碼下載】

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)點(diǎn)擊按鈕修改view標(biāo)簽背景顏色功能,涉及微信小程序事件響應(yīng)及數(shù)值運(yùn)算實(shí)現(xiàn)動態(tài)設(shè)置view背景色樣式的相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • echarts折線圖實(shí)現(xiàn)部分虛線部分實(shí)線效果的方法

    echarts折線圖實(shí)現(xiàn)部分虛線部分實(shí)線效果的方法

    在折線圖中,通常實(shí)線表示實(shí)際數(shù)據(jù),而虛線用于表示預(yù)測數(shù)據(jù),這篇文章主要介紹了echarts折線圖實(shí)現(xiàn)部分虛線部分實(shí)線效果的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • 前端實(shí)現(xiàn)json動畫詳細(xì)過程(附帶示例)

    前端實(shí)現(xiàn)json動畫詳細(xì)過程(附帶示例)

    這篇文章主要介紹了如何使用Lottie制作動畫,包括創(chuàng)建動畫文件.json、實(shí)現(xiàn)效果、在Git倉庫中保存和共享、運(yùn)行動畫以及在動畫天堂下載和顯示JSON動畫,文中通過代碼及圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2025-02-02
  • JS實(shí)現(xiàn)數(shù)組去重的11種方法總結(jié)

    JS實(shí)現(xiàn)數(shù)組去重的11種方法總結(jié)

    去重是開發(fā)中經(jīng)常會碰到的一個(gè)熱點(diǎn)問題,這篇文章主要介紹了JS中實(shí)現(xiàn)數(shù)組去重的11個(gè)方法總結(jié),文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-04-04
  • 微信小程序使用第三方庫Immutable.js實(shí)例詳解

    微信小程序使用第三方庫Immutable.js實(shí)例詳解

    Immutable 是 Facebook 開發(fā)的不可變數(shù)據(jù)集合。不可變數(shù)據(jù)一旦創(chuàng)建就不能被修改,是的應(yīng)用開發(fā)更簡單,允許使用函數(shù)式編程技術(shù),比如惰性評估。微信小程序無法直接使用Immutable.js,下面就來說說微信小程序如何使用第三方庫Immutable.js。
    2016-09-09

最新評論

谢通门县| 万源市| 虞城县| 京山县| 无极县| 阜阳市| 廉江市| 吴桥县| 泸水县| 丹凤县| 西畴县| 察雅县| 屏边| 绥棱县| 鲁山县| 罗源县| 安福县| 东山县| 中牟县| 明水县| 周至县| 公安县| 双鸭山市| 朝阳县| 丰原市| 察雅县| 内黄县| 武川县| 贵阳市| 玉环县| 阿勒泰市| 中超| 稻城县| 荥阳市| 大埔区| 山东省| 仪陇县| 诸城市| 张北县| 义乌市| 中江县|