錯誤之處茄唐,歡迎指正孝扛。
1. 原型和原型鏈
- 所有函數(shù)都有
prototype
這個屬性,這個屬性指向該函數(shù)的原型乎芳。原型是一個對象格式遵蚜。 - 所有對象都有
__proto__
這個屬性,這個屬性指向該對象的構(gòu)造函數(shù)的原型奈惑。注意:使用__proto__
是不被推薦的一種方式吭净,推薦使用Object
上的靜態(tài)方法Object.getPrototypeOf(obj)
來獲取該對象的構(gòu)造函數(shù)的原型。 - 函數(shù)也是對象肴甸,函數(shù)也具有
__proto__
這個屬性寂殉,指向構(gòu)造函數(shù)Function
的原型。 -
Function
可以理解為是javascript
幫我們寫好的原在,Function.__proto__ === Function.prototype
Object.prototype.__proto__ === null
- 當(dāng)調(diào)用一個對象/函數(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);
- 首先看
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
会钝。 - 再看
obj.b
,這里就不再贅述了,從Object.prototype
開始說迁酸,在這里依然沒找到b
先鱼,那么繼續(xù)向上找Object.prototype.__proto__
,此時返回了null
奸鬓,所以obj.b
輸出的是undefined
焙畔。 -
F.a
和F.b
,F
是一個函數(shù)串远,它自身沒有a
和b
這兩個屬性宏多,那么去它的構(gòu)造函數(shù)原型(F.__proto__
)上尋找,它的構(gòu)造函數(shù)是Function
澡罚,那么該構(gòu)造函數(shù)的原型是Function.prototype
伸但,然而依然沒有a
,但是此時找到了b
留搔,所以F.b
輸出的是22
更胖,那么繼續(xù)找Function.prototype.__proto__
,Function.prototype
是一個對象催式,它的構(gòu)造函數(shù)是Object
函喉,因此,找到了Object.prototype
荣月,所以F.a
輸出的是chris
。
3. 和原型相關(guān)的關(guān)鍵字和屬性
- 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
的原型生年。
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
的原型。
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
判斷是自身的屬性廓奕,還是原型上的屬性抱婉。
Object.create()
Object.prototype.name = 'chris';
const obj = Object.create(Object.prototype);
console.log(obj.name); //chris
以Object.prototype
為obj
的隱式原型創(chuàng)建obj
。