這裏,咱們列出原型的幾個概念,以下:javascript
__proto__
<!--more-->java
只要建立了一個函數,就會爲該函數建立一個prototype
屬性,指向該函數的原型對象。實例對象是不會擁有該屬性的。
默認狀況下,該原型對象
也會得到一個constructor
屬性,該屬性包含一個指針,指向prototype
屬性所在的函數。chrome
function Person() {}// 只是一個函數而已 Person.prototype.constructor === Person
__proto__
javascript中,不能夠訪問的內部屬性都是用[[propertyName]]
這種形式來表示的,好比還有枚舉屬性[[Enumberable]]。瀏覽器
[[prototype]]
屬性只能是對象能夠擁有的屬性。好比實例化的對象以及原型對象
,而不是構造函數。這個屬性指向擁有其屬性的對象的構造函數的原型對象。注意,此處的構造函數
指的是使用new
方式的構造函數。並不由於更改了原型對象上的constructor
屬性而改變。函數
好比:this
function Person() {} Person.prototype.constructor = {}; // 此處修改了Person原型的構造函數指向 let p = new Person(); p.__proto__ === Person.prototype; // true
__proto__
是個啥呢,就是對[[propertyName]]
的實現。也就是說,你能夠在支持該實現的瀏覽器下(FF,chrome,safari),去訪問對象的構造函數的原型對象。好比:spa
var Person = function(name) { this.name = name; }; var p1 = new Person(); p1.__proto__=== Person.prototype; // true Person.prototype = {}; var p2 = new Person(); p2.__proto__ === Object.prototype; // false
固然,__proto__
只是瀏覽器的私有實現,目前ECMAScript標準實現方法是Object.getPrototypeOf(object)
。prototype
var Person = function(name) { this.name = name; }; var p1 = new Person(); Object.getPrototypeOf(p1) === Person.prototype; // true Person.prototype = {}; var p2 = new Person(); Object.getPrototypeOf(p2) === Object.prototype; // false
另一種判斷實例對象和其原型對象存在指向關係(由實例的[[prototype]]指向其構造函數的原型對象)的方法是:isPrototypeOf
。好比:指針
Person.prototype.isPrototypeOf(p1); // true
因爲函數和原型對象
也是一個對象,因此,它天然而然也擁有[[prototype]]
屬性。code
弄清楚了這些概念,原型鏈,繼承等存在的一些問題,都不是問題了。