JS 原型以及原型鏈

2022-04-02 11:41:25 字數 4125 閱讀 4317

// 原型煉圖(點選此處放大)

* * 原型物件

* 無論什麼時,只要建立乙個新函式,就會根據一組特定的規則為該函式建立乙個 prototype 屬性

* 這個屬性指向該函式的原型物件。預設情況下,所有原型物件都會自動獲得乙個 constructor(建構函式)

* 屬性,這個屬性包含乙個指向 prototype 屬性所在函式的指標。當建構函式建立乙個新例項後,

* 該例項的內部包含乙個指標[[prototype]](內部屬性),指向建構函式的原型物件。

*//*

* * 如:

* 建立乙個函式 a:function a(){}

* function a(){} 會有乙個屬性: prototype 屬性

* function a(){} 的原型物件為: a.prototype

* function a(){} 的原型物件會自動獲得乙個 constructor 屬性: a.prototype.constructor

* 那麼:

* function a(){} 中的 prototype 屬性 ---(指向)---> a.prototype (function a(){} 的原型物件)

* a.prototype.constructor (constructor屬性) ---(指向)---> function a(){} (函式 a)

*/function

a(){}

console.log(a.prototype.constructor==a);//

true 可見原型物件中的 constructor 指向函式a/**

* 如:

* 使用 new 關鍵字結合 a() 函式來建立例項 obj

* 則 obj 這個例項會有乙個 [[prototype]] 內部屬性指向 a 的原型物件 a.prototype

* firefox、safari 和chrome 在每個物件上都支援乙個屬性 __proto__ ,它就相當於 [[prototype]]

*/var obj=new

a();

console.log(obj.__proto__==a.prototype);//

true 可見例項中的 [[prototype]] 指向函式原型 a.prototype

a.prototype.name="guang";//

給a的原型物件增加乙個name:"guang"屬性

a.prototype.sayname=function();//

給a的原型物件增加乙個sayname方法

var obj=new

a();

console.log(obj.sayname());

//guang

//

上圖展示了a 建構函式、a 的原型屬性以及a 現有的例項 obj之間的關係。

//在此,a.prototype 指向了原型物件,而a.prototype.constructor 又指回了a。

//原型物件中除了包含constructor 屬性之外,還包括後來新增的其他屬性。a 的每個例項—

//都包含乙個內部屬性,該屬性僅僅指向了 a.prototype原型物件,而建構函式沒有直接的關係。

//雖然這 obj例項不包含屬性和方法,但卻可呼叫 a.sayname(),這是通過查詢物件屬性的過程來實現的。

//每當**讀取某個物件的某個屬性時,都會執行一次搜尋,目標是具有給定名字的屬性。搜尋首先

//從物件例項本身開始。如果在例項中找到了具有給定名字的屬性,則返回該屬性的值;如果沒有找到,

////

個屬性,則返回該屬性的值。

//對於上面的例子而言,在呼叫a.sayname()的時候,會先後執行兩次搜尋

////

問:「a 的原型有sayname 屬性嗎?」答:「有。」於是,它就讀取那個儲存在原型物件中的函式。

//而這正是多個物件例項共享原型所儲存的屬性和方法的基本原理。

/*

* * 原型鏈

* 每個建構函式都有乙個原型物件,原型物件都包含乙個指向建構函式的指標,而例項都包含乙個指向原型物件的內部指標。

* 當乙個原型物件是另乙個原型物件的例項時,該原型物件將包含乙個指向另乙個原型的指標。相應地,另乙個原型中也包含著乙個指向

* 另乙個建構函式的指標。假如另乙個原型又是另乙個型別的例項,那麼上述關係依然成立,如此層層遞進,就構成了例項與原型的鏈條

*/function

supertype()

supertype.prototype.getsupervalue = function

();

function

subtype()

//繼承了supertype

subtype.prototype = new

supertype();

subtype.prototype.getsubvalue = function

();

var instance = new

subtype();

console.log(instance.getsupervalue());

//true

console.log(instance.constructor == subtype,instance.constructor == supertype); //false true

//

以上**定義兩個型別:supertype、subtype。通過建立 supertype的例項,原型物件 subtype.prototype 繼承了supertype的屬性

//本質上是通過重寫原型物件實現繼承。如圖:

在上面的**中,並沒有使用subtype 預設提供的原型,而是給它換了乙個新原型;這個新原型

//就是supertype 的例項。於是,新原型不僅具有作為乙個supertype 的例項所擁有的全部屬性和方法,

//而且其內部還有乙個指標,指向了supertype 的原型。

//最終結果就是這樣的:instance 指向subtype的原型, subtype 的原型又指向supertype 的原型。

//getsupervalue() 方法仍然還在 supertype.prototype 中,但property 則位於subtype.prototype 中。

//這是因為property 是乙個例項屬性,而getsupervalue()則是乙個原型方法。既然subtype.prototype 現在是supertype

//的例項,那麼property 當然就位於該例項中了。此外,要注意instance.constructor 現在指向的

//是supertype,這是因為subtype 的原型指向了另乙個物件——>supertype 的原型,而這個原型物件的constructor 屬性指向的是supertype。

////

instance.getsupervalue()會經歷三個搜尋步驟:1>搜尋例項;2>搜尋subtype.prototype;3>搜尋supertype.prototype,

//4>最後一步才會找到該方法。在找不到屬性或方法的情況下,搜尋過程總是要一環一環地前行到原型鏈末端才會停下來。

//

事實上,因為所有引用型別預設都繼承了object,而這個繼承也是通過原型鏈實現的。

//因此預設原型都會包含乙個內部指標,指向object.prototype。這也正是所有自定義型別都會繼承tostring()、valueof()等

方法的根本原因。對該例子來說完整的原型鏈應該如下:

js原型 原型鏈以及原型繼承簡單闡述

原型是物件資料型別所有,原型又分為顯式原型和隱式原型 語法糖形式 class person getname getage const person newperson 張三 18 person.getname 張三 person.getage 18 建構函式形式 function person na...

JavaScript原型以及原型鏈

原型物件的用途是為每個例項物件儲存共享的方法和屬性,它僅僅是乙個普通物件而已。並且所有的例項是共享同乙個原型物件,因此有別於例項方法或屬性,原型物件僅有乙份。在訪問乙個物件的屬性的時候,首先在當前物件中找,如果沒有在其原型物件找 復用的內容放在prototype,讓類的例項擁有相同的功能 小紅書上的...

JS 物件 JS原型 原型鏈

參考學習 js物件 構造器函式 建立物件的函式。物件分為普通物件和函式物件。所有物件都有 proto 屬性 函式物件不止有 proto 屬性,還有prototype屬性 稱為原型物件 1.new function 產生的物件都是函式物件。2.所有函式物件的 proto 都指向function.pro...