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

資訊專欄INFORMATION COLUMN

javascript 參數檢驗(一):實現一個方便的參數檢驗工具

maxmin / 1352人閱讀

摘要:本文嘗試編寫一種參數檢查工具,期待能緩解類似問題。為了實現鏈式調用,返回的是一個特殊的包裝對象。如果要打印出檢查失敗的參數名,需要寫成。由于德摩根定律的存在,后的參數表實際上在表達與的關系,比如表示的是參數既不為也不為。

綜述

javascript 屬于弱類型語言,參數的類型錯誤只能在運行期發現。當你需要 expose “非常健壯”的接口給外部,或者在調試較大項目的時候,你可能會懷念強類型語言的類型約束,或者 assert 一類東西。

正因為 js 沒有類型約束,也沒有 assert 這樣的“契約型”斷言工具,所以同一個人寫出的 js 代碼,健壯性常常是不穩定的,有時約束多,有時約束少,有時候返回 null,有時候拋異常,并且約束代碼也常常不統一放在函數入口處。

本文嘗試編寫一種參數檢查工具,期待能緩解類似問題。

參數檢查

假設,我們需要給所有接口統一添加穩定的約束,以及約束破壞后統一的反饋行為(比如崩潰),除了語言原生支持(聽說 Eiffel 有這個能力,有興趣的可以 google 下),最直接的方法就是設計一個類似 assert 的參數檢查函數 check,在每個函數入口處調用 check 檢查參數,如果檢查失敗則執行既定的失敗反饋。

如果所有的函數都這樣編寫,就可以保證所有函數嚴格執行約束,約束破壞后立刻停止運行,并打印相應的信息。

接口

我們很容易大致設想一個 check 接口的模樣——

check.setCheckFailedCallback(function (e) {});

function test(a) {
    check(a).檢查1(條件1).檢查2(條件2)……
}

有幾個細節需要討論一下:

上面的代碼使用了鏈式調用,鏈式調用的必要性是很顯然的——我們需要一種組合檢查步驟的方式。為了實現鏈式調用,check 返回的是一個特殊的包裝對象 Checker。

當參數 a 通過所有檢查后,代碼向下執行。如果有一個檢查沒有通過,此時需要執行一個反饋。由于外層代碼可能存在 try 塊,所以這里拋異常是不可靠的,或者說我們要想一個辦法拋出一個“不可 catch”的異常。這里采用的最簡單的辦法,上層設置回調函數 checkFailedCallback,檢查失敗后自行處理結果,同時拋出一個異常。

check(a) 這種寫法,實際上是做不到的。js 里沒有宏,所以沒有辦法接受一個變量同時拿到變量的名稱。如果要打印出檢查失敗的參數名,需要寫成 check(a, "a")。這種寫法有點累贅,可能有更好的方案,我還在思考。

邏輯組合

剛才說到鏈式調用可以用來組合檢查步驟,但是只有一種組合方式顯然是不行的。因為檢查步驟之間的關系可能有三種:與、或、非。我們要想辦法使用同一的規則把三種關系表達清楚。

具體就不解釋了,分享一下我的規則:

鏈式調用實現“與”

// a 是 number 型,并且大于 1 小于 3
check(a, "a").is("number").gt(1).lt(3);

參數表實現“或”

// a 是 number 型,并且位于 [0, 1) || (1, 2] 區間上
check(a, "a").is("number").within("[0, 1)", "(1, 2]");

注:由于參數表實現“或”,所以這里“或”的優先級永遠比“與”高,如果需要“與”比“或”高,則需要一點技巧,具體見我這篇文章。

not 屬性實現“非”

// a 是字符串并且不符合正則表達式 /^[w][wd]+$/
check(a, "a").is("string").not.match(/^[w][wd]+$/);

// a 是字符串并且不符合正則表達式 /^[w][wd]+$/, 并且長度等于 10
check(a, "a").is("string").not.match(/^[w][wd]+$/).length().eq(10);

注:

not 是一個特殊屬性,會返回一個特殊對象 NotChecker,這個對象使用 try 執行原對象的檢查方法,catch 到異常則認為檢查通過。并且 NotChecker 的檢查方法返回的是原對象而不是自己,所以 not.match 之后連接 length 時,已經不再 not 的作用范圍。

由于德摩根定律的存在,not 后的參數表實際上在表達"與"的關系,比如:

check(a, "a").not.is("string", "number").

表示的是參數 a 既不為 string 也不為 number。

其他

另外,為了方便使用,還需要實現一些另外的接口,比如:

// a 包含屬性 foo,大于 1 小于 3; 同時包含屬性 bar, 大于 2 小于 4
check(a, "a").has("foo").gt(1).lt(3).owner.has("bar").gt(2).lt(4);

注:

上面的代碼中,has 是一個特殊方法,它檢驗參數中是否包含指定的屬性(own property),如果包含,就返回一個包裝該屬性的 Checker,否則拋檢查失敗的異常。

owner 是一個特殊屬性,它返回包裝上一層對象的 Checker 對象。所以我們可以在調用 has 檢查屬性之后,調用 owner“跳回去”繼續檢查上層對象。

代碼

為了檢驗上面的想法,我實現了一個 js 庫 param-check,代碼位于:
https://github.com/yusangeng/param-check

因為只是一個語言切換是產生的 idea,所以目前這個庫還不完善,實際能有多大意義還不好說,對性能和編程范式的影響還需要評估。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87798.html

相關文章

  • javascript 參數檢驗(二):參數檢查工具完善

    摘要:上一個版本的問題接這篇文章,聊聊參數檢查工具的完善。最終實現了這樣的效果檢查是否在區間與的交集內檢查是否在區間與的并集內檢查是否是數組并且長度大于檢查是否不是之間的偶數即 上一個版本的問題 接這篇文章,聊聊參數檢查工具 param-check 的完善。 按照之前的接口設計,鏈式調用表示與,參數表表示或,自然產生了一個問題——如果我要表達(A與B)或(C與D)這樣的邏輯組合應該怎么辦? ...

    cheukyin 評論0 收藏0
  • javascript中安全地訪問深層嵌套

    摘要:介紹這是一篇短文,旨在展示多種在中安全地訪問深層嵌套值的方式。所以每次我們想要訪問深度嵌套的數據時,都必須明確地進行手動檢查。我們還觸及了,可以更新深度嵌套數據而不會改變對象。 介紹 這是一篇短文,旨在展示多種在javascript中安全地訪問深層嵌套值的方式。下面的例子通過不同的方式來解決這一問題。 開始之前,讓我們看下實際遇到這種狀況時.. 假設有一個props對象(如下),當我們...

    zacklee 評論0 收藏0
  • python做adf檢驗

    摘要:檢驗是用來檢驗序列是否平穩的方式一般來說是時間序列中的一種檢驗方法中可使用現成的工具來實現檢驗最參數和返回結果的理解還不夠深刻后頭再把參數和返回結果都加上參數項序列,一維數組差分次數只有常量,有常量項和趨勢項,有常量項線性和二次趨勢 adf檢驗是用來檢驗序列是否平穩的方式一般來說是時間序列中的一種檢驗方法python中可使用現成的工具statsmodels來實現adf檢驗 import...

    hatlonely 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<