摘要:四條大規(guī)則原型和原型鏈,大體可以用以下幾條規(guī)則概括,弄清楚了這幾條,也就基本吃透了原型和原型鏈。上圖幫助理解吧實(shí)例的隱式原型屬性指向其構(gòu)造函數(shù)的顯式原型屬性。原型相關(guān)方法判斷一個(gè)對(duì)象是否在原型鏈上可以用,判斷某一個(gè)屬性是否是自身屬性可以用。
四條大規(guī)則
原型和原型鏈,大體可以用以下幾條規(guī)則概括,弄清楚了這幾條,也就基本吃透了原型和原型鏈。
所有的引用類型都有一個(gè)__proto__屬性,屬性值是一個(gè)普通對(duì)象
所有的函數(shù)都有一個(gè)prototype屬性,屬性值也是一個(gè)普通對(duì)象
所有引用類型的__proto__屬性值指向其構(gòu)造函數(shù)的prototype屬性值
當(dāng)試圖得到一個(gè)對(duì)象的某個(gè)屬性值時(shí),如果這個(gè)對(duì)象本身沒有該屬性,就會(huì)去它的__proto__(它構(gòu)造函數(shù)的prototype)中查找
(為了方便起見,下文中__proto__用隱式原型代替,prototype用顯式原型代替)
舉個(gè)栗子:
// 構(gòu)造函數(shù) function Human(name) { this.name = name; } Human.prototype.introduce = function(){ console.log("My name is", this.name); } var somebody = new Human("somebody"); console.log(Human.prototype); // Function console.log(Human.prototype.constructor === Human); // true console.log(somebody.__proto__ === Human.prototype); // true somebody.introduce(); // "My name is somebody"
在上述例子中,Human是構(gòu)造函數(shù),而somebody是Human的一個(gè)實(shí)例。從console輸出結(jié)果可以驗(yàn)證,構(gòu)造函數(shù)的顯式原型的constructor屬性指向它本身,實(shí)例的隱式原型屬性指向其構(gòu)造函數(shù)的顯式原型。
在實(shí)例somebody中并沒有introduce方法,該方法實(shí)際是在Human.prototype中,由上述第四條,當(dāng)試圖得到一個(gè)對(duì)象的某個(gè)屬性值時(shí),如果這個(gè)對(duì)象本身沒有該屬性,就會(huì)去它的__proto__(它構(gòu)造函數(shù)的prototype)中查找,所以somebody的introduce方法實(shí)際上是somebody.__proto__.introduce,也就是Human.prototype.introduce。
上圖幫助理解吧~
實(shí)例的隱式原型屬性指向其構(gòu)造函數(shù)的顯式原型屬性。
所有的一層一層的__proto__連起來(lái),就構(gòu)成了原型鏈。例如,在Object.prototype上有一方法toString,而somebody也有,但其實(shí)somebody的toString方法并非自身所有(除非多帶帶有聲明),而是來(lái)自于somebody.__proto__.__proto__.__proto__(即Object.prototype),這一點(diǎn)可以通過(guò)hasOwnProperty證明。
判斷一個(gè)對(duì)象是否在原型鏈上可以用instanceof,判斷某一個(gè)屬性是否是自身屬性可以用hasOwnProperty。
console.log(somebody.hasOwnProperty("name")) // true console.log(somebody instanceof Object); // true //語(yǔ)法 // obj.hasOwnProperty(prop) // object instanceof constructor
后續(xù)再出一期與new運(yùn)算符相關(guān)的還有與原型繼承、class相關(guān)的吧,排期ing。
參考閱讀MDN: instanceof
MDN: constructor
MDN: hasOwnProperty
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96329.html
摘要:如下所示在規(guī)范中,已經(jīng)正式把屬性添加到規(guī)范中也可以通過(guò)設(shè)置和獲取對(duì)象的原型對(duì)象對(duì)象之間的關(guān)系可以用下圖來(lái)表示但規(guī)范主要介紹了如何利用構(gòu)造函數(shù)去構(gòu)建原型關(guān)系。 前言 在軟件工程中,代碼重用的模式極為重要,因?yàn)樗麄兛梢燥@著地減少軟件開發(fā)的成本。在那些主流的基于類的語(yǔ)言(比如Java,C++)中都是通過(guò)繼承(extend)來(lái)實(shí)現(xiàn)代碼復(fù)用,同時(shí)類繼承引入了一套類型規(guī)范。而JavaScript是...
摘要:前言文章主要基于高級(jí)程序設(shè)計(jì)總結(jié)的基本重寫了全文補(bǔ)充知識(shí)點(diǎn)新增實(shí)例優(yōu)化排版新增檢測(cè)方法技巧用法構(gòu)造函數(shù)創(chuàng)建一個(gè)用護(hù)定義的對(duì)象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對(duì)象類型之一命令執(zhí)行構(gòu)造函數(shù)返回一個(gè)實(shí)例對(duì)象構(gòu)造函數(shù)一個(gè)指定對(duì)象實(shí)例的類型的函數(shù)傳慘一 前言 文章主要基于>總結(jié)的!!!PS: 2018/05/09 基本重寫了全文,補(bǔ)充知識(shí)點(diǎn),新增實(shí)例,優(yōu)化排版PS: 2018/05/11 新增檢測(cè)...
摘要:要添加到新對(duì)象的可枚舉新添加的屬性是其自身的屬性,而不是其原型鏈上的屬性的屬性。大家可能會(huì)注意到,第一個(gè)參數(shù)使用了。也就是說(shuō)將設(shè)置成了新創(chuàng)建對(duì)象的原型,自然就不會(huì)有原型鏈上的屬性。至此,我相信大家已經(jīng)對(duì)兩者的區(qū)別十分清楚了。 在Vue和Vuex的源碼中,作者都使用了Object.create(null)來(lái)初始化一個(gè)新對(duì)象。為什么不用更簡(jiǎn)潔的{}呢?在SegmentFault和Stack...
摘要:但是該方法有個(gè)缺點(diǎn)就是看不出該對(duì)象的類型,于是乎構(gòu)造函數(shù)模式應(yīng)運(yùn)而生。當(dāng)然,如果細(xì)心的朋友應(yīng)該會(huì)發(fā)現(xiàn)函數(shù)名首字母大寫了,這是約定在構(gòu)造函數(shù)時(shí)將首字母大寫。這時(shí)候,聰明的人應(yīng)該都可以想到,將構(gòu)造函數(shù)模式和原型模式組合起來(lái)就可以了。 一.什么是js對(duì)象 1.簡(jiǎn)單理解js對(duì)象 在了解原型鏈之前,我們先要弄清楚什么是JavaScript的對(duì)象,JavaScript對(duì)象又由哪些組成。有人說(shuō)一個(gè)程...
摘要:接下解釋和屬性同樣拿上面的代碼來(lái)解釋輸出首先給構(gòu)造函數(shù)的原型對(duì)象賦給方法,由構(gòu)造函數(shù)創(chuàng)建的實(shí)例會(huì)繼承原型對(duì)象上的方法。 本文為了解決以下問(wèn)題: __proto__(實(shí)際原型)和prototype(原型屬性)不一樣!??! constructor屬性(原型對(duì)象中包含這個(gè)屬性,實(shí)例當(dāng)中也同樣會(huì)繼承這個(gè)屬性) prototype屬性(constructor.prototype原型對(duì)象) __...
閱讀 1828·2023-04-26 02:32
閱讀 576·2021-11-18 13:12
閱讀 2458·2021-10-20 13:48
閱讀 2528·2021-10-14 09:43
閱讀 3840·2021-10-11 10:58
閱讀 3516·2021-09-30 10:00
閱讀 2943·2019-08-30 15:53
閱讀 3496·2019-08-30 15:53