它極易內的CoffeeScript定義自己的DSL。如果你想創建一個類型檢查框架,例如,你可以創建一個類這樣
class A
@def foo:
params: [isNum, isBool,isNotNull]
body: (x, y, z) -> console.log "foo: #{x}, #{y}, #{z}"
@def應該創建一個方法名爲「foo」,並通過調用給定的功能檢查,根據自己的位置它的參數「params」數組。
讓我們寫一些測試第一
a = new A()
a.foo 3, true, "foo"
a.foo "string", true, "foo"
a.foo 3, "string", "foo"
a.foo 3, false, null
這時我們就需要一些輔助方法,將做實際的參數檢查
isNum = (p)-> console.log "p isnt a number its => #{p}" if typeof p != "number"
isBool = (p)-> console.log "p isnt a bool its => #{p}" if typeof p != "boolean"
isNotNull = (p)-> console.log "p is null" if p == null or p == undefined
也許他們應該做更有用的東西(比如拋出一個異常)。就我們的例子而言,它們應該足夠了
現在我們的類A調用一個尚未定義的類方法。我們將創建一個基類,這和它
class ContractBase
@def: (fndef)->
#get the name of the "function definition" object
#should be the only key
name = Object.keys(fndef)[0]
#get the real function body
fn = fndef[name]["body"]
#get the params
params = fndef[name]["params"]
# create a closure and assign it to the prototype
@::[name] = ->
#check the parameters first
for value, index in arguments
#get the check at the index of the argument
check = params[index]
#and run it if available
check(value) if check
#call the real function body
fn arguments...
#and finally change A to extend from ContractBase
class A extends ContractBase
...
顯然,在這幾個疣
- 參數數組和參數數組可以是不同lenght的繼承我們的A類(沒有檢查該還)
- 的輔助函數應該拋出一個異常
- 輔助功能應該是組合像isNotNull(ISNUM)
- 你規避定義一個方法,這樣的「正常」的方式你造成的JavaScript代碼將是難以閱讀和調試 - 也許不是
以下是完整的運行代碼在一個去
class ContractBase
@def: (fndef)->
name = Object.keys(fndef)[0]
fn = fndef[name]["body"]
params = fndef[name]["params"]
@::[name] = ->
for value, index in arguments
check = params[index]
check(value) if check
fn arguments...
isNum = (p)-> console.log "p isnt a number its => #{p}" if typeof p != "number"
isBool = (p)-> console.log "p isnt a bool its => #{p}" if typeof p != "boolean"
isNotNull = (p)-> console.log "p is null" if p == null or p == undefined
class A extends ContractBase
@def foo:
params: [isNum, isBool,isNotNull]
body: (x, y, z) -> console.log "foo: #{x}, #{y}, #{z}"
a = new A()
a.foo 3, true, "foo"
a.foo "string", true, "foo"
a.foo 3, "string", "foo"
a.foo 3, false, null
其大致1/3的相應Javascript代碼的長度,當然它的通信意圖要好得多(imo)