// 原型煉圖(點選此處放大)* * 原型物件
* 無論什麼時,只要建立乙個新函式,就會根據一組特定的規則為該函式建立乙個 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 屬性嗎?」答:「有。」於是,它就讀取那個儲存在原型物件中的函式。
//而這正是多個物件例項共享原型所儲存的屬性和方法的基本原理。
/*console.log(instance.constructor == subtype,instance.constructor == supertype); //false true* * 原型鏈
* 每個建構函式都有乙個原型物件,原型物件都包含乙個指向建構函式的指標,而例項都包含乙個指向原型物件的內部指標。
* 當乙個原型物件是另乙個原型物件的例項時,該原型物件將包含乙個指向另乙個原型的指標。相應地,另乙個原型中也包含著乙個指向
* 另乙個建構函式的指標。假如另乙個原型又是另乙個型別的例項,那麼上述關係依然成立,如此層層遞進,就構成了例項與原型的鏈條
*/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
//以上**定義兩個型別: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...