js類(繼承)(二)

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;

 

能夠參考:http://www.jb51.net/article/44875.htm

相關文章
相關標籤/搜索