原型和原型鏈

錯誤之處,歡迎指正。


1. 原型和原型鏈

  1. 所有函數(shù)都有prototype這個屬性,這個屬性指向該函數(shù)的原型。原型是一個對象格式。
  2. 所有對象都有__proto__這個屬性,這個屬性指向該對象的構(gòu)造函數(shù)的原型。注意:使用__proto__是不被推薦的一種方式,推薦使用Object上的靜態(tài)方法Object.getPrototypeOf(obj)來獲取該對象的構(gòu)造函數(shù)的原型。
  3. 函數(shù)也是對象,函數(shù)也具有__proto__這個屬性,指向構(gòu)造函數(shù)Function的原型。
  4. Function可以理解為是javascript幫我們寫好的,Function.__proto__ === Function.prototype
  5. Object.prototype.__proto__ === null
  6. 當(dāng)調(diào)用一個對象/函數(shù)上的屬性時(shí),先去自身找,如果自身沒有,去__proto__上找(構(gòu)造該對象的構(gòu)造函數(shù)的原型,xxx.__proto__),如果構(gòu)造函數(shù)的原型上沒有,去該構(gòu)造函數(shù)的原型的__proto__上找(構(gòu)造函數(shù)的原型的構(gòu)造函數(shù)的原型xxx.__proto__.__proto__),一直到找到,或者返回null為止。

2. 例題

const F = function () {};  //構(gòu)造函數(shù)F
const obj = new F();  //構(gòu)造函數(shù)F構(gòu)造的對象obj
Object.prototype.a = 'chris';
Function.prototype.b = '22';
console.log(obj.a);
console.log(obj.b);
console.log(F.a);
console.log(F.b);
  1. 首先看obj.a,obj是一個對象,它自身沒有a這個屬性,那么去它的構(gòu)造函數(shù)原型(obj.__proto__)上尋找,它的構(gòu)造函數(shù)是F,那么該構(gòu)造函數(shù)的原型是F.prototype,然而依然沒有,那么繼續(xù)找F.prototype.__proto__F.prototype是一個對象,它的構(gòu)造函數(shù)是Object,因此,找到了Object.prototype,所以obj.a輸出的是chris
  2. 再看obj.b,這里就不再贅述了,從Object.prototype開始說,在這里依然沒找到b,那么繼續(xù)向上找Object.prototype.__proto__,此時(shí)返回了null,所以obj.b輸出的是undefined。
  3. F.aF.bF是一個函數(shù),它自身沒有ab這兩個屬性,那么去它的構(gòu)造函數(shù)原型(F.__proto__)上尋找,它的構(gòu)造函數(shù)是Function,那么該構(gòu)造函數(shù)的原型是Function.prototype,然而依然沒有a,但是此時(shí)找到了b,所以F.b輸出的是22,那么繼續(xù)找Function.prototype.__proto__,Function.prototype是一個對象,它的構(gòu)造函數(shù)是Object,因此,找到了Object.prototype,所以F.a輸出的是chris

3. 和原型相關(guān)的關(guān)鍵字和屬性

  1. instanceof
const obj = {};
function a() {};
console.log(obj instanceof Object);  //true
console.log(obj instanceof Function);  //false
console.log(a instanceof Object);  //true
console.log(a instanceof Function);  //true

簡單來說,可以把instanceof當(dāng)做“是”,例如上述:
obj是個對象”,就正確;“obj是個方法”,很明顯這是不正確的。實(shí)際上,instanceof是判斷obj的原型鏈上是否有Object的原型。

  1. isPrototypeOf
const obj = {};
function a() {}
console.log(Object.prototype.isPrototypeOf(obj));  //true
console.log(Function.prototype.isPrototypeOf(obj));  //false
console.log(Object.prototype.isPrototypeOf(a));  //true
console.log(Function.prototype.isPrototypeOf(a));  //true

通過isPrototypeOf來判斷obj的原型鏈上是否有object的原型。

  1. hasOwnProperty
Object.prototype.age = '22';
const obj = {
    name: 'chris'
}
console.log(obj.name); //chris
console.log(obj.age);  //22
console.log(obj.hasOwnProperty('name'));  //true
console.log(obj.hasOwnProperty('age'));  //false

判斷是自身的屬性,還是原型上的屬性。

  1. Object.create()
Object.prototype.name = 'chris';
const obj = Object.create(Object.prototype);
console.log(obj.name);  //chris

Object.prototypeobj的隱式原型創(chuàng)建obj。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 眾所周知js原型及原型鏈?zhǔn)呛芏嚅_發(fā)者的一個疼點(diǎn)(我也不例外),我也曾多次被問起,也問過不少其他人,如果在自己沒有真...
    奔跑的痕跡閱讀 464評論 0 6
  • 為什么要理解原型和原型鏈,因?yàn)橛欣谖覀兝斫夂蛯?shí)現(xiàn) JS對象繼承。 __proto__ __proto__是什么W...
    微風(fēng)玉米閱讀 590評論 0 2
  • 構(gòu)造函數(shù)是一種特殊的方法。主要用來在創(chuàng)建對象時(shí)初始化對象, 即為對象成員變量賦初始值,總與new運(yùn)算符一起使用在創(chuàng)...
    Primers閱讀 196評論 0 0
  • 記住一句“內(nèi)功”: 「對象.__proto __ === 函數(shù).prototype」 一. prototype原...
    Jason_Shu閱讀 391評論 0 0
  • 一、原型 上回講到,生成一個對象我們可以通過new構(gòu)造函數(shù)來實(shí)現(xiàn),如下: 但是,上面這樣也有個缺陷,比如每個per...
    Da_xiong閱讀 420評論 0 1

友情鏈接更多精彩內(nèi)容