Javascript 理解 __proto__ 和 prototype以及instance

1. 以下這張圖,基本解釋了所有的原型關係

原型關係圖

核心要素是:

var Foo = function (){}
var foo = new Foo()
foo.__proto__ == foo.constructor.prototype == Foo.prototype

// .__proto__ 其實是 .construstor.prototype 的簡寫

其實應該不是簡寫,當我把對象的constructor置爲null.__proto__還是能夠讀到,但是.constructor.prototype直接報錯了。這裏這麼說只是爲了方便理解
說到底.__proto__就是這個對象的構造函數的原型。

理解了這個就能理解上面圖示的所有的關係了。


2. 以下點有助於理解幾個基類之間的關係

instanceof 操作符

instanceof的左值一般是一個對象,右值一般是一個構造函數,用來判斷左值是否是右值的實例。它的內部實現原理是這樣的:

//設 L instanceof R 
//通過判斷
 L.__proto__.__proto__ ..... === R.prototype ?
 //最終返回true or false

也就是沿着L的__proto__一直尋找到原型鏈末端,直到等於R.prototype爲止。知道了這個也就知道爲什麼以下這些奇怪的表達式爲什麼會得到相應的值了

 Function instanceof Object // true 
 Object instanceof Function // true 
 Function instanceof Function //true
 Object instanceof Object // true
 Number instanceof Number //false

3. 總結了下

Object.constructor == function Function (){}
Function.constructor == function Function (){}


兩個需要特殊注意一下, 記住這個基本上能把所有的東西都推理出來了。


1.Function.prototype 結果爲 functoin (){ // native code }

2.Function.prototype.constructor 結果爲 Funtion 本身

3.Function.prototype.constructor.prototype 結果爲 function (){// native code }

...無線循環

4.Function.prototype.__proto__ 結果爲 Object.prototype

5.Object.prototype.__proto__ 爲 null

4. 關於 proto

__proto__ 是內部的構造函數原型對象, 一般情況下

obj.__proto__ === obj.constructor.prototype // true

但是__proto__不會因爲你在對象的prototype中更改constructor而改變。它總是指向對象被創建時的那個constructor function , 舉個例子:

// 在學習原型鏈的時候是這樣繼承的

function Animal(){}

function Dog(){}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog; // 在繼承的時候,這裏改變了prototype.constructor,但是不影響__proto__的結果

// 完成繼承

new Dog() instanceof Animal // true
new Dog() instanceof Dog // true

// 根據以上 instanceof 的原理

new Dog().__proto__.__proto__ === Animal.prototype // true

// 在這裏__proto__和constructor.prototype是不一樣的, 

new Dog().__proto__.constructor.prototype ===  Animal.prototype // false


部分內容摘自
作者:蘇墨橘
鏈接:https://www.zhihu.com/question/34183746/answer/59043879

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章