1. 定義js類
js並非一種面向對向的語言, 沒有提供對類的支持, 所以咱們不能像在傳統的語言裏那樣 用class來定義類, 但咱們能夠利用js的閉包封裝機制來實現js類, 咱們來封裝一個簡的Shape類.編程
代碼以下:閉包
function ShapeBase() {
this.show = function()
{
alert("ShapeBase show");
};
this.init = function(){
alert("ShapeBase init");
};
}app
這個類裏定義了兩個方法:show和init, 須要注意的是這裏用到了this來聲明, 而不是var, 由於用var是用來定義私有方法的.
另外, 咱們還能夠用prototype屬性來定義Shape的方法.函數
代碼以下:測試
ShapeBase.prototype={
show:function()
{
alert("ShapeBase show");
},
init:function() {
alert("ShapeBase init");
}
};this
如今, 類是寫好了, 讓咱們寫個js來測試下, 看看結果是否是跟咱們想象的同樣呢?.net
代碼以下:prototype
function test(src){
var s=new ShapeBase();
s.init();
s.show();
}htm
看到了吧, 其調用方式和C#如出一轍, 而結果也如咱們所料.
到目前爲止, 咱們學會了如何建立js的類了, 但還只是實例方法,要是實現跟C#中的靜態方法要怎麼作呢?
其實, 實現js的靜態方法很簡單, 看下面如何實現:對象
代碼以下:
//靜態方法
ShapeBase.StaticDraw = function()
{
alert("method draw is static");
}
2. 實現JS類抽象和繼承
function Animal(){
this.species = "動物";
}
1、 構造函數綁定
第一種方法:也是最簡單的方法,使用call或apply方法,將父對象的構造函數綁定在子對象上,即在子對象構造函數中加一行:
function Cat(name,color){
Animal.apply(this, arguments);
this.name = name;
this.color = color;
}
var cat1 = new Cat("大毛","黃色");
alert(cat1.species); // 動物
2、 prototype模式
第二種方法更常見,使用prototype屬性。
若是"貓"的prototype對象,指向一個Animal的實例,那麼全部"貓"的實例,就能繼承Animal了。
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黃色");
alert(cat1.species); // 動物
代碼的第一行,咱們將Cat的prototype對象指向一個Animal的實例。
Cat.prototype = new Animal();
它至關於徹底刪除了prototype 對象原先的值,而後賦予一個新值。可是,第二行又是什麼意思呢?
Cat.prototype.constructor = Cat;
原來,任何一個prototype對象都有一個constructor屬性,指向它的構造函數。若是沒有"Cat.prototype = new Animal();"這一行,Cat.prototype.constructor是指向Cat的;加了這一行之後,Cat.prototype.constructor指向Animal。
alert(Cat.prototype.constructor == Animal); //true
更重要的是,每個實例也有一個constructor屬性,默認調用prototype對象的constructor屬性。
alert(cat1.constructor == Cat.prototype.constructor); // true
所以,在運行"Cat.prototype = new Animal();"這一行以後,cat1.constructor也指向Animal!
alert(cat1.constructor == Animal); // true
這顯然會致使繼承鏈的紊亂(cat1明明是用構造函數Cat生成的),所以咱們必須手動糾正,將Cat.prototype對象的constructor值改成Cat。這就是第二行的意思。
這是很重要的一點,編程時務必要遵照。下文都遵循這一點,即若是替換了prototype對象,
o.prototype = {};
那麼,下一步必然是爲新的prototype對象加上constructor屬性,並將這個屬性指回原來的構造函數。
o.prototype.constructor = o;