原型和原型鏈,大致能夠用如下幾條規則歸納,弄清楚了這幾條,也就基本吃透了原型和原型鏈。函數
(爲了方便起見,下文中__proto__用隱式原型代替,prototype用顯式原型代替)
舉個栗子:this
// 構造函數 function Human(name) { this.name = name; } Human.prototype.introduce = function(){ console.log('My name is', this.name); } var somebody = new Human('somebody'); console.log(Human.prototype); // Function console.log(Human.prototype.constructor === Human); // true console.log(somebody.__proto__ === Human.prototype); // true somebody.introduce(); // "My name is somebody"
在上述例子中,Human是構造函數,而somebody是Human的一個實例。從console輸出結果能夠驗證,構造函數的顯式原型的constructor屬性指向它自己,實例的隱式原型屬性指向其構造函數的顯式原型。spa
在實例somebody中並無introduce方法,該方法實際是在Human.prototype中,由上述第四條,當試圖獲得一個對象的某個屬性值時,若是這個對象自己沒有該屬性,就會去它的__proto__(它構造函數的prototype)中查找,因此somebody的introduce方法其實是somebody.__proto__.introduce,也就是Human.prototype.introduce。prototype
上圖幫助理解吧~code
實例的隱式原型屬性指向其構造函數的顯式原型屬性。
全部的一層一層的__proto__連起來,就構成了原型鏈。例如,在Object.prototype上有一方法toString,而somebody也有,但其實somebody的toString方法並不是自身全部(除非單獨有聲明),而是來自於somebody.__proto__.__proto__.__proto__(即Object.prototype),這一點能夠經過hasOwnProperty證實。對象
判斷一個對象是否在原型鏈上能夠用instanceof,判斷某一個屬性是不是自身屬性能夠用hasOwnProperty。blog
console.log(somebody.hasOwnProperty('name')) // true console.log(somebody instanceof Object); // true //語法 // obj.hasOwnProperty(prop) // object instanceof constructor
後續再出一期與new運算符相關的還有與原型繼承、class相關的吧,排期ing。繼承