javaScript中__proto__與prototype的區別與聯絡

來源:互聯網
上載者:User

最近在學習javascript的原型,發現了__proto__與prototype,學問很大,於是研究了一下。

首先解釋一下什麼是原型。 

原型是一個對象,其他對象可以通過它實現屬性繼承。

對象又是什麼呢。

在javascript中,一個對象就是任何無序索引值對的集合,如果它不是一個主要資料類型(undefined,null,boolean,number,array,string),那它就是一個對象。

那麼如何查看一個對象的原型是啥呢。又如何給一個對象設定原型呢。

標準對象原型訪問器Object.getPrototype(object),到目前為止只有Firefox和chrome實現了此訪問器。除了IE,其他的瀏覽器支援非標準的訪問器__proto__,而prototype則是一個只有函數才具有的屬性,

也就是說,如果這個對象不是函數,那麼它就沒有prototype這個屬性。

下面代碼證實了以上結論。

<script>var a={name:'derek'};var b=function(name){name=this.name;};document.write(a.prototype+"<br>");//undefined 對象a顯然不是一個函數,所以沒有prototype這個屬性。document.write(Object.getPrototypeOf(a)+"<br>");//[object Object]document.write(Object.getPrototypeOf(b)+"<br>");//function Empty() {}document.write(Object.getPrototypeOf(b)==b.__proto__);//true  這兩個的是等價的,只不過瀏覽器的相容型不同。</script>


再說一下javascript的建構函式

1、建構函式和普通的函數一樣,但是具有以下兩個特殊性質。

2、通常建構函式的首字母是大寫的(讓識別建構函式變得更容易)。建構函式通常要和 new 操作符結合,用來構造新對象。

下面這個例子很厲害~

基於所知道的知識,請想象建立一個新的對象,並讓新對象表現地像數組的過程。一種方法是使用下面的代碼。

1 2 3 4 5 6 // 建立一個新的Null 物件 var o = {}; // 繼承自同一個原型,一個數組對象 o.__proto__ = Array.prototype; // 現在我們可以調用數組的任何方法... o.push(3);

雖然這段代碼很有趣,也能工作,可問題在於,並不是每一個 JavaScript 環境都支援可寫的 __proto__ 對象屬性。幸運的是,JavaScript 確實有一個建立對象內建的標準機制,只需要一個操作符,就可以建立新對象,並且設定新對象的 __proto__ 引用 – 那就是“new”操作符。

1 2 var o = new Array(); o.push(3);

JavaScript 中的 new 操作符有三個基本任務。首先,它建立新的Null 物件。接下來,它將設定新對象的 __proto__ 屬性,以匹配所調用函數的原型屬性。最後,操作符調用函數,將新對象作為“this”引用傳遞。如果要擴充最後兩行代碼,就會變成如下情況:

1 2 3 4 var o = {}; o.__proto__ = Array.prototype; Array.call(o); o.push(3);

函數的 call 方法允許你在調用函數的情況下在函數內部指定“this”所引用的對象。當然,函數的作者在這種情況下需要實現這樣的函數。一旦作者建立了這樣的函數,就可以將其稱之為建構函式。

我們來測試一下,

var Person=function(name,age){this.name=name;this.age=age;document.write("hello,I'm "+name+" and "+age+" years old"+"<br>");}var p1=new Person('derek',23);document.write(Object.getPrototypeOf(p1)==Person.prototype);//truedocument.write(p1.__proto__==Person.prototype);//true 兩種訪問對象原型的方式會得到相同的結果,前提是非IE6、7、8瀏覽器。。

可以上面的理論是正確的~

我們接著做實驗,看一下繼承是怎麼實現的~

var Person=function(name,age){this.name=name;this.age=age;document.write("hello,I'm "+name+" and "+age+" years old"+"<br>");}Person.prototype.smile=function(){document.write("O(∩_∩)O~"+"<br>");}var p1=new Person('derek',23);p1.smile();

輸出: hello,I'm derek and 23 years old
O(∩_∩)O~

首先,p1這個對象沒有smile這個函數,於是去__proto__屬性上去找,因為p1.__proto__==Person.prototype,而Person.prototype上恰好有這個函數,因此就會出現上面的運行結果。這個是最簡單的原型鏈,如果Person.prototype上還沒有smile()這個函數,那麼就會去Person.__proto__去繼續找,依次類推。




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.