犀牛書學習筆記(8):理解原型和對象

前面講到,javascript是基於原型的面嚮對象語言,本篇將對javascript中原型的理解,從而理解javascript如何構建對象體系。舉個例子,基於類的對象和基於原型的對象構建方式區別在於:建立「人」這對象的時候,及魚類的方式是定義人的模型,而後按照人的模型建立一我的。基於原型的方式是經過人的基因(原型)來建立一我的。javascript

原型的由來java

全部函數都有一個原型屬性,當函數被定義的時候,原型自動建立和初始化,原型的初始化值是一個對象,該對象只有一個屬性:constructor,該屬性指向原型相關聯的的構造函數。添加給原型對象的任何屬性,都會被被構造函數初始化的對象的屬性。對象從類實例化而來,類定義從構造函數開始,參見類定義章節的說明。chrome

在執行操做符new的時候,構造函數的原型就被設置爲構造函數的原型的值。就這樣全部的對象在默認的狀況下都有一個原型屬性,由於原型自己也是對象,因此每一個原型自身又有一個原型(只有一種例外,默認的對象原型在原型鏈的頂端)。一個對象的真正原型是被對象內部的[[Prototype]]屬性(property)所持有。原型屬性被初始化爲一個對象,ECMA引入了標準對象原型訪問器Object.getPrototype(object),到目前爲止只有Firefox和chrome實現了此訪問器。函數

下面的代碼展現了獲取對象原型的方法this

var a = {}; 
Object.getPrototypeOf(a); //獲取對象a的原型   
a.__proto__; //獲取對象a原型的非標準方法,原型是對象的屬性
a.constructor.prototype; //經過構造函數得到對象a的原型

 

若是想獲取基本數據類型如int、false的原型,會自動轉換爲其封裝對象,只有對象才具備原型。spa

到這裏,就能夠很好地理解爲何經過構造函數能夠建立對象,構造函數也是函數,有一個原型屬性,new一個構造函數的時候,基於構造函數的原型建立了對象實例。構造函數初始化prototype

的對象從原型哪裏繼承了全部的屬性和方法,所以原型是放置方法和不變屬性的理想的地方。code

經過下面的代碼來講明原理對象

function A() {                           //定義構造函數a
    this.width = 10;
    this.data = [1,2,3];
    this.key = "this is A";
}

A._objectNum = 0;                        //定義A的私有屬性
A.prototype.say = function(){
    alert("hello");
}                                        //給A的原型對象添加屬性

var a = new A();                         //建立一個對象實例
a.say();                                 //調用方法 

 

原型鏈 blog

由於每一個對象和原型都有一個原型(注:原型也是一個對象),對象的原型指向對象的父,而父的原型又指向父的父,咱們把這種經過原型層層鏈接起來的關係撐爲原型鏈。這條鏈的末端通常老是默認的對象原型。和基於類的面向對象的繼承同樣,原型的繼承實現了基於原型的對象的繼承。

對象在查找某個屬性的時候,會首先遍歷自身的屬性,若是沒有則會繼續查找[[Prototype]]引用的對象,若是再沒有則繼續查找[[Prototype]].[[Prototype]]引用的對象,依次類推,直到[[Prototype]].….[[Prototype]]undefinedObject[[Prototype]]就是undefined)。

相關文章
相關標籤/搜索