最近在面試胖笛,幾乎每家公司都有被問到原型相關(guān)的問題网持,雖然看過不少文章,但總感覺自己每次回答的時(shí)候都沒辦法把這個(gè)知識點(diǎn)講得清楚长踊,想來還是多借鑒一些文章功舀,然后結(jié)合自己的面試經(jīng)歷來整理一下。
首先什么是原型身弊?
JavaScript中除了基本類型外的數(shù)據(jù)類型辟汰,都是對象。但是由于其沒有類(class阱佛,ES6引入了class帖汞,但只是語法糖)的概念,如何將所有對象聯(lián)系起來就成了一個(gè)問題瘫絮,于是就有了原型和原型鏈的概念涨冀。
簡單來說,原型和原型鏈?zhǔn)荍S中解決繼承的一種方案麦萤。
原型鏈又是如何實(shí)現(xiàn)的鹿鳖?
當(dāng)談到繼承時(shí),JavaScript 只有一種結(jié)構(gòu):對象壮莹。每個(gè)實(shí)例對象( object )都有一個(gè)私有屬性(稱之為 __proto__ )指向它的構(gòu)造函數(shù)的原型對象(prototype )翅帜。該原型對象也有一個(gè)自己的原型對象(__proto__ ) ,層層向上直到一個(gè)對象的原型對象為 null命满。根據(jù)定義涝滴,null 沒有原型,并作為這個(gè)原型鏈中的最后一個(gè)環(huán)節(jié)胶台。
一些跟原型相關(guān)的重要的知識點(diǎn):
- 每一個(gè)構(gòu)造函數(shù)都擁有一個(gè)prototype屬性歼疮,這個(gè)屬性指向一個(gè)對象,也就是原型對象诈唬。當(dāng)使用這個(gè)構(gòu)造函數(shù)創(chuàng)建實(shí)例的時(shí)候韩脏,prototype屬性指向的原型對象就成為實(shí)例的原型對象。
- 原型對象默認(rèn)擁有一個(gè)constructor屬性铸磅,指向指向它的那個(gè)構(gòu)造函數(shù)(也就是說構(gòu)造函數(shù)和原型對象是互相指向的關(guān)系)赡矢。
每個(gè)對象都擁有一個(gè)隱藏的屬性[[prototype]]杭朱,指向它的原型對象,這個(gè)屬性可以通過 - Object.getPrototypeOf(obj) 或 obj.__proto__ 來訪問吹散。
實(shí)際上弧械,構(gòu)造函數(shù)的prototype屬性與它創(chuàng)建的實(shí)例對象的[[prototype]]屬性指向的是同一個(gè)對象,即 對象.__proto__ === 函數(shù).prototype 空民。 - 原型對象就是用來存放實(shí)例中共有的那部分屬性刃唐。
- 在JavaScript中,所有的對象都是由它的原型對象繼承而來,反之,所有的對象都可以作為原型對象存在称簿。
- 訪問對象的屬性時(shí)丰歌,JavaScript會(huì)首先在對象自身的屬性內(nèi)查找,若沒有找到报辱,則會(huì)跳轉(zhuǎn)到該對象的原型對象中查找与殃。
總結(jié):
- 當(dāng) new 一個(gè)函數(shù)的時(shí)候會(huì)創(chuàng)建一個(gè)對象,『函數(shù).prototype』 等于 『被創(chuàng)建對象.__proto__』
- 一切函數(shù)都是由 Function 這個(gè)函數(shù)創(chuàng)建的碍现,所以『Function.prototype === 被創(chuàng)建的函數(shù).__proto__』
- 一切函數(shù)的原型對象都是由 Object 這個(gè)函數(shù)創(chuàng)建的幅疼,所以『Object.prototype ===
一切函數(shù).prototype.__proto__』