首先寫一個簡單的類。java
function Animal(nickName){ this.getNickName = function(){return nickName}; } Animal.prototype.canMiaomiao=false; Animal.prototype.eat=function(){console.log("animal eat");}; Animal.prototype.sleep=function(){console.log("animal sleep");};
上面實現了一個普通動物的類。nickName爲其私有域,canSpeak爲公有域。此類還有三個方法 getNickName, eat, sleep。框架
而後寫一個子類。this
function Cat(nickName, color) { this.superClass(nickName); this.getColor=function(){return color;}; } Cat.prototype=new Animal(); Cat.prototype.constructor=Cat; Cat.prototype.superClass=Animal; Cat.prototype.canMiaomiao=true; Cat.prototype.eat=function(){this.superClass.prototype.eat.call(this); console.log('cat eat');}; Cat.prototype.catchMouse=function(){console.log('catch mouse');};
Cat繼承Animal,多了一個私有域color,多了新方法catchMouse,重寫了方法eat,在eat中還調用了父類中的方法。運行下面代碼,看發生了什麼。
var a = new Animal('animal'); a.eat(); a.sleep(); a.getNickName(); var b = new Cat('cat','black'); b.eat(); b.catchMouse(); b.sleep(); b.getColor(); b.getNickName();
上面都是JS語法裏面提供的方法。但這種方法只提供了單繼承。若是想實現多繼承,那須要引入新的方法mixin。在dojo中,mixin就是將一個object中的屬性所有複製到另外一個object。假設有兩個父類A,B,如今須要設計一個子類,同時繼承A和B,那麼能夠將A和B的屬性所有mixin到C中,也能夠C繼承A後再minxin B。Dojo便使用了此方法實現多繼承。prototype
不少JS框架,都爲了更好的結構化,模擬java似的面向對象。在java中,初始化一個類使用defineClass。dojo則設計了dojo.declare這一方法來聲明一個類。下面的代碼便定義了咱們JS中的defineClass,雖然它只實現了單繼承,但從中可見一斑。設計
// 傳入參數爲JSON, JSON中包含的properties以下。 // className: /*String*/ // extend: /*function*/ // constructor: /*function*/ // methods and fields: /*properties*/ // 下面代碼不考慮容錯性。 function defineClass(/*JSON*/data) { var className = data.className; var constructor = data.constructor || function(){}; var superClass = data.extend || Object; var proto = new superClass(); for (var property in data) { proto[property] = data[property]; } proto.constructor = constructor; proto.superClass = superClass; proto.className = className; constructor.prototype=proto; window[className] = constructor; }
有了以上這個簡單的defineClass,咱們能夠換一種方式來動態的加載Animal和Cat類。code
var AnimalClass = { className:'Animal', constructor: function(nickName){ this.getNickName = function(){return nickName}; }, extend:null, canMiaomiao:false, eat:function(){console.log("animal eat");}, sleep:function(){console.log("animal sleep");} }; defineClass(AnimalClass); var CatClass = { className:'Cat', constructor: function(nickName, color) { this.superClass(nickName); this.getColor=function(){return color;}; }, extend:Animal, canMiaomiao:true, eat:function(){this.superClass.prototype.eat.call(this); console.log('cat eat');}, catchMouse:function(){console.log('catch mouse');} }; defineClass(CatClass); var a = new Animal('animal'); var b = new Cat('cat');
以上只是簡單的defineClass。Dojo的多繼承比這要複雜不少,好比如何調用父類的方法。可是原理是很是相近的。這裏就再也不仔細分析了。若是有問題,請留言。