JS中class的實現方式,另模擬dojo.declare

首先寫一個簡單的類。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的多繼承比這要複雜不少,好比如何調用父類的方法。可是原理是很是相近的。這裏就再也不仔細分析了。若是有問題,請留言。
相關文章
相關標籤/搜索