1. 程式人生 > >Javascript中的原型繼承具體解釋

Javascript中的原型繼承具體解釋

value ase dsm ext art 是什麽 結合 通過 原型繼承

js中的繼承,是面向對象的知識,由於js沒有類的概念。所以繼承是通過對象實現的。談到繼承。就必須說到prototype,就不得不先說下new的過程。
一個小小的列子:

<script type="text/javascript">
        var Person = function () { };
        var p = new Person();
    </script>

我們來看看這個new到底做了什麽?我們能夠把new的過程拆分成以下三步:

<1> var p={}; 也就是說。初始化一個對象p。

<2> p.proto=Person.prototype;

<3> Person.call(p);也就是說構造p。也能夠稱之為初始化p。

關鍵在於第二步,我們來證明一下:

alert(p.__proto__ === Person.prototype);

這段代碼會返回true。說明我們步驟2的正確。

那麽proto是什麽?我們在這裏簡單地說下。每一個對象都會在其內部初始化一個屬性。就是proto,當我們訪問一個對象的屬性 時。假設這個對象內部不存在這個屬性,那麽他就會去proto裏找這個屬性,這個proto

又會有自己的proto,於是就這樣 一直找下去,也就是我們平時所說的原型鏈的概念。

依照標準,proto是不正確外公開的,也就是說是個私有屬性,可是Firefox的引擎將他暴露了出來成為了一個共同擁有的屬性,我們能夠對外訪問和設置。

<script type="text/javascript"> var Person = function () { };
        Person.prototype.Say = function () {
        alert("Person say");
    }
    var p = new Person();
    p.Say();
    
</script>

這段代碼非常easy。相信每一個人都這樣寫過,那就讓我們看下為什麽p能夠訪問Person的Say。

首先var p=new Person();能夠得出p.proto=Person.prototype。那麽當我們調用p.Say()時,首先p中沒有Say這個屬性, 於是,他就須要到他的proto中去找。也就是Person.prototype,而我們在上面定義了 Person.prototype.Say=function(){}; 於是,就找到了這種方法。

以下我們再看一下有點挑戰的。

function tiger(){
   this.bark=function(){
   alert("我會咬人");
   };
};
//這裏先定義一個老虎方法


function cat(){
  this.climb=function(){
   alert("我會爬樹");
};
};

//定義一個貓方法


//怎麽通過繼承讓老虎也學會爬樹?以下開始繼承。

tiger.prototype=new cat(); var hnhu=new tiger(); hnhu.climb(); hnhu.valueof(); //是不是非常奇妙,老虎也會怕會啦。嘿嘿

結合上面的概念,我分析一下詳細的繼承過程,首先new一個tiger對象。有hnhu.proto=tiger.prototype,有由於tiger.prototype=new cat();
所以tiger.prototype.proto=cat.prototype。至此繼承已經付出水面。轉化一下得到:

hnhu.proto=tiger.prototype
hnhu.proto.proto=cat.prototype

好,算清楚了之後我們來看上面的結果,hnhu.climb()。由於hnhu沒有climb這個屬性。於是去hnhu.proto。也就是 tiger.prototype中去找,由於tiger.prototype中也沒有climb,那就去hnhu.proto.proto,也就是cat.prototype中去找,於是就找到了alert(“我會爬樹”);的方法。

尋找valueof()也都是相同的道理。這條鏈就形成了原型鏈,繼承也就通過原型鏈得以實現。

以上代碼圖示:

技術分享圖片

原型和原型鏈就是這樣。跟作用域和作用域鏈相似,須要慢慢品味當中的精華。

掌握了在來實際用一下把。企鵝的一道繼承面試題,大概意思是一僅僅狗剛開始會嗚嗚的叫。然後發生某種變異,叫聲變為變異。

function dog(){
    this.fark=function(){
        alert("嗚嗚");
    };
};

function peter(){
    this.money=function(){
        alert("我是有錢狗");
    };
};

peter.prototype=new dog();
peter.prototype.bark=function(){
    alert("變異");
};
var tz=new peter();
tz.bark();
tz.fark();

你還能夠在Object.prototype上添加一些新屬性。加入上之後無論是不是變異狗都具有這項屬性。由於Object處於原型鏈的倒數第二層,上面的方法都會繼承它的屬性。

Javascript中的原型繼承具體解釋