當前位置:
首頁 > 知識 > 原型原型鏈學習記錄

原型原型鏈學習記錄

這是一篇學習筆記。

個人心得:

關於原型和原型鏈這一塊,很難,但是,一旦理解,就通了。

對於這一塊,我之前不懂的時候,非要去弄明白,特別痛苦,之後,看到了王福朋老師的閉包原型系列,真的是茅塞頓開!看完之後,我就拿起JavaScript高程3,高程3第6章節,耐心跟著看也就明白了。之後,再去做一些圖解,如果能夠根據繼承畫出所有的關係,沒有矛盾的點,那就基本沒問題了。再到網上找差不多的文章看,如果沒有衝突點,那這一塊就沒問題了。

參考的內容:

你不知道的JavaScript 上

JavaScript高級程序設計 3

內容:

一些名詞的解釋 +幾個圖解(所以圖片會比較多) 。

1:簡單的實例

2:完整的實例

3:重寫原型對象

4:原型繼承

原型/繼承

JavaScript中的對象都有一個內置屬性 [[prototype]]屬性。在表示的時候可以用__proto__表示。

__proto__: 每個對象都有這樣一個屬性,指向該對象的構造函數的prototype的指向

所有原型鏈的最後指向都是null。

除了Object.create,無實參直接創建的對象的原型是null/沒有原型,即不繼承任何屬;其餘的對象的原型鏈上null之前都有一個Object.prototype原型對象。

Object的prototype對象的[[prototype]]內部屬性的值是null。即:Object.prototype.__proto__ === null //true。

所有通過對象直接量創建的對象都有一個共同的原型對象:Object.prototype

原型原型鏈學習記錄

通過關鍵字new和構造函數調用創建的對象的原型就是構造函數的prototype屬性所指向的對象。

(當通過new和構造函數生成實例,實例的原型對象就會鎖定)。

JavaScript中的內建函數以及用戶自定義函數都是通過Function 這個函數創建的

所有的函數默認都會擁有一個名為prototype的不可枚舉的屬性。這個屬性指向一個對象,被稱為這個函數的原型對象。

每個原型有一個不可枚舉的屬性constructor。這個屬性引用的是對象關聯的函數,即constructor屬性的值是一個函數對象。

Function是由它自己創建的,所以:

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

原型原型鏈學習記錄

new 調用構造函數的一個重要特徵

構造函數的prototype屬性值被用做新對象的原型。即通過同一個構造函數創建的對象都繼承自同一個對象。

原型原型鏈學習記錄

原型原型鏈學習記錄

構造函數,原型對象,實例它們都是對象!

instanceof:左邊走__proto__,右邊走prototype,如果能重合,返回true,否則,返回false。

A instanecof B,一般,A是一個函數,B是一個對象。

使用new的構造函數調用會生成prototype和constructor引用。

如何理解函數,對象,實例,原型,構造函數之間的關係,圖解是非常好的方式,所謂有圖有真相

可以通過原型鏈(通過__proto__串在一起的原型形成了一條鏈)把它們串在一起理解。

1:

function Foo{ /*...*/}
var a1=new Foo;
var a2=new Foo;

這是一個非常簡單的構造函數和實例對象。

原型原型鏈學習記錄

這樣,它們的關係圖就出來了。

實例a1,a2,函數Fun1,原型Fun1.prototype,都是對象.。

函數Fun1有一個prototype屬性,指向一個對象,名為Fun1.prototype,成為Fun1的原型對象。

原型對象Fun1.prototype有一個constructor屬性,指向該對象關聯的函數。

實例a1,a2都有一個__proto__,指向該實例的構造函數的prototype的指向,並且它們指向的是同一個原型對象,因為a1,a2都是通過new和Fun1構造函數調用生成的實例。

這個圖是比較基本的,並沒有展現所有的關係,下一張圖會進一步展現它們的關係。

2:

原型原型鏈學習記錄

對象都有[[prototype]]屬性,屬性值為該對象構造函數的prototype值。

上面的構造函數,原型對象,實例,都是對象,所以它們都有[[prototype]]屬性,即它們都繼承自某一原型。

其中null不是實例,null是空對象,什麼都沒有。

因為函數Fun1是用戶自定義函數,Object,Function是內置函數,都是函數,所以就是通過Function 函數創建的,所以,它們的原型就是Function.prototype.

Function.prototype.上有call和apply方法,所有的函數都繼承自它,所以,所有的函數都能夠擁有這兩個方法。

因為:除了Object.create,無實參直接創建的對象的原型是null/沒有原型,即不繼承任何屬;其餘的對象的原型鏈上null之前都有一個Object.prototype原型對象。

所以,原型對象和實例的原型都指向了Object.prototype。

3重寫原型對象 :

function Foo{/*...*/}
var a1=new Foo; //用new調用之後就會鎖定原型
Foo.prototype={/*...*/}; //創建一個新原型對象,重寫Foo的prototype
var a2=new Foo;

圖3:

原型原型鏈學習記錄

註:

新的Foo.prototype 就是Object的實例。

舊的Foo.prototype 不會消失,依然會存在。因為實例a1的原型會指向它,實例a1繼承它,在通過new調用生成實例的時候,a1就會鎖定它的原型。

Foo.prototype.constructor === Object; //true

a2.constructor === Object; //true

但是,實際上Foo.prototype和a2都沒有constructor屬性,它們都是繼承自Object.prototype。原型才有constructor這個屬性,其他對象的constructor都是繼承自原型。

4:繼承

function SuperType{
this.property=true;
}
SuperType.prototype.getSuperValue=function{
return this.property;
};
function SubType{
this.subproperty=false;
}
SubType.prototype=new SuperType; //繼承自SuperType /重寫了原型

SubType.prototype.getSuperValue=function{
return this.subproperty;
};
var instance=new SubType;

原型原型鏈學習記錄

(這張圖片源自高程3)

這裡也可以比較清楚地看到對象的關係和對象所擁有的屬性集合。

原型原型鏈學習記錄

這是一個簡單的原型繼承,通過圖解關係就可以看到上面代碼,方便理解。

舊的SubType.prototype 依然存在,不過這裡它沒有實例去引用它。新的SubType.prototype 是作為SuperType的實例存在,繼承自SuperType.prototype 。

從instance開始,通過__proto__連接,直到null,就形成了一條原型鏈,上層的屬性會被下層繼承。

以上就是我的理解,如果有錯誤,還請各位前邊指正,謝謝。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 科技優家 的精彩文章:

JStorm與Storm源碼分析(四)——均衡調度器,EvenScheduler
編寫使用多線程的希爾排序(shell sort)
ABP從入門到精通(2):aspnet-zero-core 使用MySql資料庫

TAG:科技優家 |

您可能感興趣

上衣原型與袖原型的紙樣設計
日本文化原型——第七代上身原型
歷史原型挖掘系列
從模型到原型
貓為原型 紙藝作品
JS學習筆記 對象、包裝類、原型、原型鏈、命名空間、對象枚舉
史努比的原型
童裝原型製版教程
大事件人物原型!
我首台多通道原子磁力計新型腦磁圖原型機研製成功
服裝打版-男裝上衣原型與袖原型
誰是穆桂英的歷史原型
EOS增材製造助力新型印刷電路板原型
我國首台多通道原子磁力計新型腦磁圖原型機研製成功
初學紙樣必讀—服裝工業女裝原型推板
「龍」的原型是蟒蛇
《諾亞方舟漂流記》中草原獵貓的原型
10大經典電影角色與歷史原型人物對比:鋼鐵俠的原型原來是他
《海賊王》30位人物原型大揭秘!路飛的原型原來是他
六片法女裝原型