解析原型鏈

來源:互聯網
上載者:User

標籤:資訊   als   空間   實現   his   cto   分享圖片   func   this   

首先,建立一個建構函式:

function Person(name,age){        this.name=name;        this.age=age;        this.eat=function(){            console.log("吃");        }    }

接著,我們執行個體化兩個對象:

     var stu1 = new Person("小明",20);     var stu2 = new Person("小花",30);

我們調用兩個對象的eat方法:

    stu1.eat();    stu2.eat();

  結果肯定是:吃  吃

但是:這兩個方法不是同一個方法

   console.log(stu1.eat===stu2.eat);//false

這是為什麼呢?

  每個執行個體對象都有自己的eat方法,而這個eat方法不是共用的

 

如果我要建立100個對象,方法的實現是一樣的,但卻不能共用,豈不是很浪費空間?

天無絕人之路,通過原型的方式是可以解決的:

  原型添加方法: 

Person.prototype.eat=function(){        console.log("吃東西");    }

  此時建構函式和原型對象中都有eat方法,預設先找建構函式,建構函式沒有找原型對象,原型對象沒有undefind

  我們刪掉之前建構函式中的eat(),此時:

   console.log(stu1.eat===stu2.eat);//true

  原型的作用:解決資料共用,節省記憶體空間

那麼原型對象是什麼呢?

  Person() 是一個建構函式,我們通過console.dir(Person),查看他的詳細資料,

  

  發現該建構函式有一個屬性prototype,該屬性也是一個對象,標準屬性,是給程式員使用的,這個屬性叫做原型對象。

 

  stu1是一個執行個體對象,我們通過console.dir(stu1),查看他的詳細對象

  

  發現該執行個體對象有一個屬性__proto__,該屬性也是一個對象,非標準屬性,給瀏覽器使用的,這個屬性叫做原型對象。

從stu1的詳細中看到他並沒有eat()方法,那麼他是如何訪問這個方法的呢?

  我們開啟prototype這個屬性:

  

  執行個體對象中沒有eat(),建構函式中的prototype中有eat()

  由此推出:執行個體對象的__proto__的指向和該執行個體對象所在的建構函式的prototype的指向相同,

       那麼執行個體對象就可以直接存取prototype中的方法了

下面圖中的construtor是什嗎?

                                                                  

  執行個體對象的__proto__中的constructor就是該執行個體對象所在的建構函式               建構函式中的prototype中的constructor指向的是原型對象所在的建構函式

而建構函式、執行個體對象、原型對象三者之間的關係是什麼呢?

  (1)執行個體對象是通過建構函式建立的

  (2)建構函式中prototype叫原型對象

  (3)建構函式中的prototype中有constructor叫構造器,指向的是該原型對象所在的建構函式

  (4)執行個體對象中__proto__叫原型對象

  (4)執行個體對象中__proto__指向的是該執行個體對象所在的建構函式的prototype

 

 

說到這裡我們就要開始推導原型鏈了:

  可以這麼理解:原型鏈就是執行個體對象和原型對象之間的一種關係

  我們說:建構函式中有prototype,執行個體對象中有__proto__

      執行個體對象的__proto__指向的是該執行個體對象所在的建構函式中的prototype

  換句話說就是:對象的__proto__指向的肯定是某個函數的prototype

  往下看:

  

  建構函式中prototype是對象,這個prototype中有__proto__也是對象,那麼這個__proto__指向的是誰呢?

    它指向的肯定是某個建構函式的prototype

    此時,觀察它的構造器的指向----是Object()

    那麼得出結論:    

   Person.prototype.__proto__===Object.prototype//true

  

    繼續觀察Person():

    

    我們之前說建構函式中有prototype,但是我此時也發現了建構函式中有__proto__,

    既然看到了__proto__,逆推思想:說明這個函數實際上也是一個對象(因為對象中有__proto__);

    所以Person()的__proto__指向的肯定是其建構函式的prototype;

    對象是通過建構函式建立的,那麼Person()的建構函式又是誰呢?

      看Person.__proto__.constructor的指向--------Function()

    得出結論:   

   Person.__proto__===Function.prototype//true

    這個時候我們知道了:

      js中的函數實際上都是通過Function這個建構函式來建立的(來執行個體化出來的);

    接下來,我們往下深挖,Function

    

    由此推出:  

   Function.prototype.__proto__===Object.prototype//true

    

    由此推出:

   Function.__proto__=== Function.prototype;//true

    

    接下來,還有最後一個Object

    

      由此推出:   

    Object.__proto__=== Function.prototype;//true

      

      

    Object的prototype中沒有__proto__   

   Object.prototype.__proto__ === null;

 

總結原型鏈:

  

解析原型鏈

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.