这里,咱们列出原型的几个概念,以下: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
弄清楚了这些概念,原型链,继承等存在的一些问题,都不是问题了。