1. 程式人生 > >JavaScript中的原型與原型鏈

JavaScript中的原型與原型鏈

權威指南 等於 develop 調用 指向 整理 高級程序設計 tps 實例

  一直對JavaScript的原型與繼承不了解,參考《JavaScript權威指南(第六版)》和《JavaScript高級程序設計(第三版)》對這個點的知識做個整理,方便自己記憶。以下內容大部分摘錄自這兩本書

每一個JavaScript對象都有與之相關的原型對象(prototype)。

原型對象有什麽用?

  JavaScript對象會繼承原型對象的屬性。

原型對象是從哪裏來的?

  首先我們先了解下創建對象基本的方式:

//1,對象直接量
var a={},b={m:1}
//2,構造函數
var c=new Object(),d=new Date();
//3,Object.create(param);
var x=Object.create(d);

  1.使用對象直接量創建的對象使用Object.prototype作為它們的原型對象;

  2.通過new創建的對象以構造函數的prototype屬性作為原型對象

  3.通過Object.create()創建的對象使用第一個參數作為它們的原型對象;

  說明:任何函數都可以是構造函數,比如有一個函數F,當使用 var f=new F()創建對象時,F就是對象f的構造函數;其他情況下F就是一個普通的函數

除了通過Object.create()創建的對象的原型是我們自己指定的外,Object.prototype和構造函數的prototype屬性又是怎麽來的呢?

  1.Object.prototype是JavaScript內置的原型對象,定義了toString,valueOf等方法及一些屬性。當我們通過var a={}創建對象a,雖然我們沒有為a定義toString方法,但是當我們調用a.toString()的時候會返回"[object Object]",這是因為這個方法已經在Object.prototype定義了。

  2.當我們創建函數的時候,JavaScript就會為該函數創建一個prototype屬性。請看代碼:

function F(){}

console.info(F.prototype);//{constructor: ?}
console.info(F.prototype.constructor===F);//
true

原型鏈是什麽?

先了解一下JavaScript對象原型的例外,在JavaScript中有少數對象是沒有原型對象的。

  1.Object.prototype

  2.null

  3.通過Object.create(null)創建的對象;

  除上述對象外,所有的JavaScript對象默認都有一個原型對象。原型對象也是一個對象實例,如果它不屬於上述3類對象,那麽它也有自己的原型對象。比如a的原型對象是b,b的原型對象是c,c的原型對象是d……直到遇到上述3類沒有原型對象的對象,從而在a,b,c,d……之間構成了一個鏈,a-->b-->c-->d……,這就是原型鏈。

原型鏈有什麽用?

  當在a中尋找一個屬性,如果有返回屬性值;如果沒有就去b中找,有就返回屬性值;如果沒有就去c中找……,如果找到鏈的末端,還沒找到就返回undefined。即通過原型鏈,實現了對象對原型鏈上的對象的繼承。

  說明:處在原型鏈前端的屬性會隱藏後面對象的同名屬性。比如:查找屬性x,b和c中都有屬性x,a.x的值等於b.x,而c中的x被隱藏了。

擴展原型鏈

  構造函數有默認的原型對象,這個原型對象的原型對象是Object.prototype。那麽,通過new加構造函數創建對象,原型鏈上只會有三個對象,如何擴展這個原型鏈呢?請看代碼:

//本段代碼來自於《JavaScript高級程序設計(第三版)》163頁
function
SuperType(){   this.property = true; } SuperType.prototype.getSuperValue = function(){   return this.property; }; function SubType(){   this.subproperty = false; } //繼承了 SuperType SubType.prototype = new SuperType();
SubType.prototype.getSubValue
= function (){ return this.subproperty; }; var instance = new SubType(); alert(instance.getSuperValue()); //true

  紅色代碼處,我們修改了SubType函數的prototype屬性的指向,使它指向了SuperType的一個對象實例。這個當我們通過new SubType()創建對象instance時,instance的原型對象是SuperType實例,而SuperType實例的原型對象是SuperType.prototype,SuperType.prototype的原型對象是Object.prototype。這樣我們就擴展了對象instance的原型鏈。進而,我們也可以把SuperType.prototype設置為別的對象實例而再次擴展原型鏈。以此類推,我們可以無限擴展原型鏈。

  可以看到通過原型鏈,可以在JavaScript中實現簡單的繼承:對象會繼承自己原型鏈上的對象的屬性。關於繼承更進一步的知識請看《JavaScript高級程序設計(第三版)》6.3繼承一節,講的很詳細。

以上就是對JavaScript原型最簡單的總結。請各路大俠批評指正!

JavaScript中的原型與原型鏈