錯誤之處,歡迎指正。
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ù)上的屬性時(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__,此時(shí)返回了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,但是此時(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)鍵字和屬性
- 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。