鴨式辨型來自於James Whitecomb Riley的名言:"像鴨子一樣走路並且嘎嘎叫的就叫鴨子。"通過制定規則來判定對象是否實現這個接口。
創建接口類,主要用來保存信息到實例類中
var Interface = function (name, methods) { this.name = name; this.method = methods; }
自定義接口,接口中定義了接口名稱和一些方法名稱。這里創建一個Duck接口,Duck接口中定義了swim, cry, foots方法。說得簡單些,接口就是自定義規則。我定義了會游泳,會嘎嘎叫,有兩條腿的就是鴨子。
var Duck = new Interface('Duck', ['swim', 'cry', 'foots'])
創建檢測方法。它用來檢測對象中有沒有實現Duck接口中所有的方法,如果有就認為這個對象實現了Duck接口;否則就認為沒有實現。
Interface.ensureImplements = function (obj, interface) { var canNotFoundMethods = []; for(var i = 0, len = interface.method.length; i < len; i++) { //檢測對象有沒有接口中所有方法 if(!interface.method[i] || typeof obj[interface.method[i]] !== 'function') { canNotFoundMethods.push(interface.method[i]); } } if(canNotFoundMethods.length){ throw new Error(obj.name+'實例對象沒有實現'+interface.name+'接口'); }else{ console.log(obj.name+'實例對象已經實現'+interface.name+'接口'); } }
創建被檢測的對象_new_duck。這個對象繼承了三個方法。
var duck = function (){ this.name = 'duck'; } duck.prototype = { 'swim': function (){}, 'cry': function (){}, 'foots': function (){}, } var _new_duck = new duck();
最后檢測,如果_new_duck中有Duck接口定義的所有方法,那么我們就可以認為_new_duck對象實現了Duck接口。我們前面定義了鴨子是會游泳,會嘎嘎叫,還有兩條腿,所有符合這規則定義的就可以稱為鴨子。正如_new_duck擁有了Duck接口所有定義的方法。
Interface.ensureImplements(_new_duck, Duck);
總結:
鴨式辨型理解起來並不困難。實現接口實際上是檢測對象是否擁有接口定義的所有方法。接口只是用來定義某些方法名稱,它並不需要實現這些方法,比如Duck接口中不需要實現swim方法。接口要做的是記住方法名稱。
Duck.swim(); //Duck接口並不需要實現swim方法