Javascript中的原型繼承的一些見解與看法

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

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

咱們來看看這個new究竟作了什麼?咱們能夠把new的過程拆分紅如下三步:

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

  • <2> p.proto=Person.prototype;面試

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

關鍵在於第二步,咱們來證實一下:spa

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

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

那麼proto是什麼?咱們在這裏簡單地說下。每一個對象都會在其內部初始化一個屬性,就是proto,當咱們訪問一個對象的屬性 時,若是這個對象內部不存在這個屬性,那麼他就會去proto裏找這個屬性,這個proto又會有本身的proto,因而就這樣 一直找下去,也就是咱們平時所說的原型鏈的概念。code

按照標準,proto是不對外公開的,也就是說是個私有屬性,可是Firefox的引擎將他暴露了出來成爲了一個共有的屬性,咱們能夠對外訪問和設置。對象

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

這段代碼很簡單,相信每一個人都這樣寫過,那就讓咱們看下爲何p能夠訪問Person的Say。blog

首先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處於原型鏈的倒數第二層,上面的方法都會繼承它的屬性,可是這樣有必定的問題,全部的狗都具備這個原型鏈中的方法了。

相關文章
相關標籤/搜索