js的原型和原型鏈

此文章幾乎是來(lái)自大牛mqyqingfeng,畢竟人家總結(jié)的直觀又更容易理解

prototype

function  Person() { } 
Person.prototype.name  =  'Kevin'; 
var person1 =  new  Person(); 
var person2 =  new  Person();
console.log(person1.name) // Kevin  
console.log(person2.name) // Kevin
// 雖然寫在注釋里,但是你要注意: 
// prototype是函數(shù)才會(huì)有的屬性

該函數(shù)的prototype指向調(diào)用構(gòu)造函數(shù)而創(chuàng)建出來(lái)的實(shí)例的原型(對(duì)象)浦马,也就是例子中的person1息堂,person2.故我們修改Person函數(shù)的prototype屬性宣蠕,實(shí)例化的對(duì)象能夠訪問(wèn)。

原型圖解

__proto__

這是每一個(gè)JavaScript對(duì)象(除了 null )都具有的一個(gè)屬性阔逼,叫 __proto__
這個(gè)屬性會(huì)指向該對(duì)象的原型

console.log(person.__proto__ === Person.prototype); // true

于是我們更新下關(guān)系圖

理解為該構(gòu)造函數(shù)實(shí)例化出來(lái)的對(duì)象的__proto__指向該構(gòu)造函數(shù)的prototype(也就是該對(duì)象person1地沮,person2的原型)

原型圖解

問(wèn)題:既然實(shí)例對(duì)象和構(gòu)造函數(shù)都可以指向原型嗜浮,那么原型是否有屬性指向構(gòu)造函數(shù)或者實(shí)例呢?
答案:指向?qū)嵗經(jīng)]有摩疑,因?yàn)橐粋€(gè)構(gòu)造函數(shù)可以生成多個(gè)實(shí)例危融。但原型指向構(gòu)造函數(shù)還是有的,

接下來(lái)就是我們要提到的第三個(gè)屬性constructor雷袋,每個(gè)原型都有一個(gè) constructor 屬性指向關(guān)聯(lián)的構(gòu)造函數(shù)吉殃。

constructor

console.log(Person === Person.prototype.constructor); // true

所以再更新下關(guān)系圖:


原型圖解

綜上我們已經(jīng)得出:


function  Person() { }
var person =  new  Person(); 
console.log(person.__proto__ == Person.prototype) // true 
console.log(Person.prototype.constructor  == Person) // true  

// 順便學(xué)習(xí)一個(gè)ES5的方法,可以獲得對(duì)象的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

二丶實(shí)例與原型

當(dāng)讀取實(shí)例的屬性時(shí),如果找不到,就會(huì)查找與對(duì)象關(guān)聯(lián)的原型中的屬性蛋勺,如果還查不到瓦灶,就去找原型的原型,一直找到最頂層為止迫卢。

function  Person() { }
Person.prototype.name  =  'Kevin'; 
var person =  new  Person();
person.name  =  'Daisy'; 
console.log(person.name) // Daisy 
delete person.name; 
console.log(person.name) // Kevin(對(duì)象關(guān)聯(lián)的原型中的name屬性)

從 person 對(duì)象中找不到 name 屬性就會(huì)從 person 的原型也就是 person.__proto__ 倚搬,也就是 Person.prototype中查找,要是再找不到就去原型的原型去查找,那什么是原型的原型呢乾蛤?

我們理解原型是一個(gè)對(duì)象每界,那么對(duì)象都是由原始new Object()來(lái)創(chuàng)建的(原型對(duì)象就是通過(guò) Object 構(gòu)造函數(shù)生成的),結(jié)合之前所講家卖,實(shí)例的__proto__指向構(gòu)造函數(shù)的 prototype 眨层,所以我們?cè)俑孪玛P(guān)系圖:

原型圖解

那 Object.prototype 的原型呢?

console.log(Object.prototype.__proto__ === null) // true

順便還要說(shuō)一下上荡,圖中由相互關(guān)聯(lián)的原型組成的鏈狀結(jié)構(gòu)就是原型鏈趴樱,也就是\color{blue}{藍(lán)色}的這條線。

面試題:
請(qǐng)問(wèn)你如何理解JavaScript原型鏈酪捡?

  • 1.JavaScript中每個(gè)對(duì)象都有一個(gè)prototype屬性叁征,我們稱之為原型,而原型的值也是一個(gè)對(duì)象逛薇,因此它也有自己的原型捺疼,這樣就串聯(lián)起來(lái)了一條原型鏈,原型鏈的鏈頭是object永罚,它的prototype.__proto__啤呼,值為null。
  • 2.原型鏈的作用是用于對(duì)象繼承呢袱,函數(shù)A的原型屬性(prototype property)是一個(gè)對(duì)象官扣,當(dāng)這個(gè)函數(shù)被用作函數(shù)來(lái)創(chuàng)建實(shí)例時(shí),該函數(shù)的原型屬性被作為原型賦值給所有對(duì)象實(shí)例羞福,比如我們新建一個(gè)數(shù)組惕蹄,數(shù)組的方法便從數(shù)組的原型上繼承而來(lái)。
  • 3.當(dāng)訪問(wèn)對(duì)象的一個(gè)屬性時(shí)坯临,首先查找對(duì)象本身焊唬,找到則返回;未找到則繼續(xù)查找原型對(duì)象的屬性(如果還找不到實(shí)際上還會(huì)沿著原型鏈向上查找看靠,直至到根)赶促。只要沒(méi)有被覆蓋的話,對(duì)象原型的屬性就能在所有的實(shí)例中找到挟炬,若整個(gè)原型鏈未找到則返回undefined鸥滨。

補(bǔ)充

最后嗦哆,補(bǔ)充三點(diǎn)大家可能不會(huì)注意的地方:

  • constructor

首先是 constructor 屬性,我們看個(gè)例子:

function  Person() { } 
var person =  new  Person(); 
console.log(person.constructor  === Person); // true

當(dāng)獲取 person.constructor 時(shí)婿滓,其實(shí) person 中并沒(méi)有 constructor 屬性,當(dāng)不能讀取到constructor 屬性時(shí)老速,會(huì)從 person 的原型也就是 Person.prototype 中讀取,正好原型中有該屬性凸主,所以:

person.constructor === Person.prototype.constructor

  • __proto__

其次是__proto__ 橘券,絕大部分瀏覽器都支持這個(gè)非標(biāo)準(zhǔn)的方法訪問(wèn)原型,然而它并不存在于 Person.prototype 中卿吐,實(shí)際上旁舰,它是來(lái)自于 Object.prototype ,與其說(shuō)是一個(gè)屬性嗡官,不如說(shuō)是一個(gè) getter/setter箭窜,當(dāng)使用 obj.__proto__ 時(shí),可以理解成返回了 Object.getPrototypeOf(obj)衍腥。

  • 真的是繼承嗎磺樱?

最后是關(guān)于繼承,前面我們講到“每一個(gè)對(duì)象都會(huì)從原型‘繼承’屬性”婆咸,實(shí)際上竹捉,繼承是一個(gè)十分具有迷惑性的說(shuō)法,引用《你不知道的JavaScript》中的話尚骄,就是:

繼承意味著復(fù)制操作活孩,然而 JavaScript 默認(rèn)并不會(huì)復(fù)制對(duì)象的屬性,相反乖仇,JavaScript 只是在兩個(gè)對(duì)象之間創(chuàng)建一個(gè)關(guān)聯(lián),這樣询兴,一個(gè)對(duì)象就可以通過(guò)委托訪問(wèn)另一個(gè)對(duì)象的屬性和函數(shù)乃沙,所以與其叫繼承,委托的說(shuō)法反而更準(zhǔn)確些诗舰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末警儒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子眶根,更是在濱河造成了極大的恐慌蜀铲,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件属百,死亡現(xiàn)場(chǎng)離奇詭異记劝,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)族扰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門厌丑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)定欧,“玉大人,你說(shuō)我怎么就攤上這事怒竿】仇” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵耕驰,是天一觀的道長(zhǎng)爷辱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)朦肘,這世上最難降的妖魔是什么饭弓? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮厚骗,結(jié)果婚禮上示启,老公的妹妹穿的比我還像新娘。我一直安慰自己领舰,他們只是感情好夫嗓,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著冲秽,像睡著了一般舍咖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锉桑,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天排霉,我揣著相機(jī)與錄音,去河邊找鬼民轴。 笑死攻柠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的后裸。 我是一名探鬼主播瑰钮,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼微驶!你這毒婦竟也來(lái)了浪谴?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤因苹,失蹤者是張志新(化名)和其女友劉穎苟耻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體扶檐,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凶杖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了款筑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片官卡。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝗茁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出寻咒,到底是詐尸還是另有隱情哮翘,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布毛秘,位于F島的核電站饭寺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏叫挟。R本人自食惡果不足惜艰匙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抹恳。 院中可真熱鬧员凝,春花似錦、人聲如沸奋献。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瓶蚂。三九已至糖埋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窃这,已是汗流浹背瞳别。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杭攻,地道東北人祟敛。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像兆解,于是被迫代替她去往敵國(guó)和親垒棋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 一、 JS創(chuàng)建對(duì)象的方法 1. 簡(jiǎn)單方式 我們可以直接通過(guò) new Object() 創(chuàng)建: 每次創(chuàng)建通過(guò) new...
    Black_List灬閱讀 316評(píng)論 0 0
  • 構(gòu)造函數(shù)創(chuàng)建對(duì)象: Person 就是一個(gè)構(gòu)造函數(shù),我們使用 new 創(chuàng)建了一個(gè)實(shí)例對(duì)象 person proto...
    饕餮潴閱讀 101,184評(píng)論 19 143
  • Mileszhuer閱讀 276評(píng)論 0 6
  • 敬愛(ài)的李老師青瀑,智慧的班主任酿联,親愛(ài)的學(xué)兄們:大家好!我是來(lái)自廣饒亨通農(nóng)機(jī)馬云芹扮饶,今天是我的日精進(jìn)行動(dòng)第375天具练,給大...
    云_300a閱讀 121評(píng)論 0 0
  • 我記憶里的銀幕開(kāi)始了: 時(shí)間:1998年秋,地點(diǎn):沈陽(yáng)第五中學(xué)高一八班甜无,人物:我和一群洋溢著青春諧趣的...
    配音木成閱讀 295評(píng)論 0 1