成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

javascript 參數(shù)檢驗(一):實現(xiàn)一個方便的參數(shù)檢驗工具

maxmin / 1359人閱讀

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

綜述

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

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

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

參數(shù)檢查

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

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

接口

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

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

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

有幾個細節(jié)需要討論一下:

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

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

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

邏輯組合

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

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

鏈式調用實現(xiàn)“與”

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

參數(shù)表實現(xiàn)“或”

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

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

not 屬性實現(xiàn)“非”

// 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 執(zhí)行原對象的檢查方法,catch 到異常則認為檢查通過。并且 NotChecker 的檢查方法返回的是原對象而不是自己,所以 not.match 之后連接 length 時,已經(jīng)不再 not 的作用范圍。

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

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

表示的是參數(shù) a 既不為 string 也不為 number。

其他

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

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

注:

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

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

代碼

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

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

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

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

相關文章

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

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

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

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

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

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

    hatlonely 評論0 收藏0

發(fā)表評論

0條評論

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