之前面試的時候遇到過原型和原型鏈方面的題目,具體的已經忘了,只記得當時回答的稀里糊塗,今天查了一些資料,把自己所理解的寫出來,加深記憶。
1,前提
在js中,對象都有__proto__屬性,一般這個是被稱為隱式的原型,該隱式原型指向構造該對象的構造函數的原型。
函數比較特殊,它除了和其他對象一樣有__proto__屬性,還有自己特有的屬性----prototype,這個屬性是一個指針,指向一個包含所有實例共享的屬性和方法的對象,稱之為原型對象。原型對象也有一個constructor屬性,該屬性指回該函數。
2,題目分析
網上找了一個題目,先分析一下
var F = function () {} Object.prototype.a = function () {} Function.prototype.b = function () {} var f = new F()
// 請問f有方法a 方法b嗎
f的__proto__指向F.prototype,F.prototype.__proto__指向Object.prototype,所以f 可以取到a方法, 由於f的原型鏈上沒經過Function.prototype,所以取不到b方法。
由於構造函數F是由Function new出來的,所以F.__proto__指向Function.prototype,所以F函數可以取到b方法。
另外一道題目:
function Person(){} let p1 = new Person() let p2 = new Person()
let obj = {}
具體的題目我忘記了,差不多就是寫出 p1 p2 Person Function obj Object等的原型鏈。
p1: __proto__ : Person.prototype
p2: __proto__ : Person.prototype
Person : __proto__: Function.prototype, prototype: Person.prototype
Person.prototype : __proto__ : Object.prototype , constructor: Person
Function: __proto__ : Function.prototype, prototype: Function.prototype
Function.Prototype: __proto__ : Object.prototype , constructor: Function
obj: __proto__ : Object.prototype
Object: __proto__ : Function.prototype , prototype: Object.prototype
Object.prototype: __proto__ : null , constructor : Object
具體的就是上面這些了,有兩個點需要注意下
1,Function.__proto__ === Function.prototype
謹記上面的紅字部分,每個對象都有__proto__,指向生成該對象的構造函數的原型。 這里Function是一個構造函數,那么它也是一個函數,既然是函數,那也是由Function這個構造函數生成的,也就是它自己本身,所以它的__proto__就指向它自己的prototype
上面的說法是錯誤的,這里參考了一位大佬的話語: Function.prototype是引擎創造出來的對象,一開始就有了,又因為其他的構造函數都可以通過原型鏈找到Function.prototype,Function本身也是一個構造函數,為了不產生混亂,就將這兩個聯系到一起了。
2,Object.__proto__ === Function.prototype
Object是對象的構造函數,那么它也是一個函數,當然它的__proto__也是指向Function.prototype
這里放一張關於這方面的經典的圖