1. 程式人生 > >JS原型的理解

JS原型的理解

我們先理解原型之前,先來看看prototype和__proto__的區別;
1、prototype是函式Function才有的屬性;
2、JS中每個物件都有一個__proto__屬性;
例:

var a = {};
console.log(a.prototype);  //undefined
console.log(a.__proto__);  //Object {}

var b = function(){}
console.log(b.prototype);  //b {}
console.log(b.__proto__);  //function() {}

__proto__指向了誰

__proto__的指向取決於物件建立時的實現方式,看下面3個例子;

var a = {};
console.log(a.__proto__  == Object.prototype);  //true

function P(){}; var b = new P();
console.log(b.__proto__  == P.prototype);  //true
console.log(b instanceof P);  //true


var obj1 = {}
var obj2 = Object.create(obj1)
console.log(obj2.__proto__ == obj1)
//true

看一個有意思的現象

Function instanceof Object;   //true
Object instanceof Function;   //true

我們知道instanceof是檢測一個物件是否是另一個物件new出來的例項
(例:var a = new Object(); a instanceof Object 返回 true)
我們來把他翻譯成人類可以看懂的語音

//假設instanceof運算子左邊是L,右邊是R
L instanceof R 
//instanceof運算時,通過判斷L的原型鏈上是否存在R.prototype
L.__proto__.__proto__ ...
.. === R.prototype ? //如果存在返回true 否則返回false

注意:instanceof運算時會遞迴查詢L的原型鏈,即L.proto.proto.proto.proto…直到找到了或者找到頂層為止。
看到這有些不理解了,這些直接有什麼聯絡嗎?
答案是肯定的,千絲萬縷啊。

原型鏈

我們例一個基礎例子;

function Parent(){}
var child = new Parent()

我們把這個程式碼的整個原型鏈用圖畫出來就是這樣的;

在這裡插入圖片描述

然後得到的結果是這樣的

console.log(child.__proto__ == Parent.prototype)  //true
console.log(child.__proto__.constructor == Parent)  //true
console.log(Parent.prototype.constructor == Parent)  // true

console.log(Parent.__proto__ == Function.prototype)  //true
console.log(Parent.__proto__.constructor == Function)  //true
console.log(Parent.__proto__.__proto__ === Object.prototype)  //true

console.log(child.__proto__.__proto__ == Function.__proto__.__proto__) //true
console.log(child.__proto__.__proto__ == Object.prototype)  //true
console.log(child.__proto__.__proto__.__proto__)  //null

console.log(Function.__proto__.constructor === Function) //true
console.log(Function.__proto__ === Function.prototype)  //true
console.log(Function.__proto__ === Object.__proto__)  //true
console.log(Object.__proto__ === Object.prototype;)  //false
console.log(Function.__proto__.__proto__ == Object.prototype) //true

清楚了prototype與__proto__的概念與關係之後我們會對“Js中一切皆為物件”這句話有更加深刻的理解。
我們可以理解__proto__是所有物件都內建的屬性,而且指向父類的原型。