prototype
每个函数都有一个 prototype 属性,它其实是个对象。
__ proto __
在 JavaScript 中,每个实例对象都有一个私有属性[[Prototype]]
,该属性指向了这个实例对象的原型,你可以通过 ES6 的 Object.getPrototypeOf() 来访问该属性,许多浏览器也对 [[Prototype]]
进行了实现,也就是我们经常见到的 __proto__
,没错,__proto__
指向了实例对象的原型,它也是一个对象。
constructor
constructor 这个字段的内容是一个函数,函数名和构造函数竟然一样。可以说,每个原型对象都有一个 constructor 属性,指向相关联的构造函数,所以构造函数和构造函数的 prototype 是可以相互指向的。

小结
JavaScript 对象(除了 null)在创建的时候就会关联一个对象,这个对象就是原型,每一个对象都会从原型上继承属性,原型也是对象,所以原型也有原型对象,层层往上,直到Object.prototype,这就是原型链。对象都会有一个 __proto__
属性来访问自己的原型,同时这个原型就是生成该对象的构造函数的 prototype 属性值。每个原型对象都有一个 constructor 属性,指向相关联的构造函数。
我们知道函数都是通过 new Function()
生成的,难道 Function.prototype
也是通过 new Function()
产生的吗?答案也是否定的,这个函数也是引擎自己创建的。首先引擎创建了 Object.prototype
,然后创建了 Function.prototype
,并且通过 __proto__
将两者联系了起来。这里也很好的解释了上面的一个问题,为什么 let fun = Function.prototype.bind()
没有 prototype
属性。因为 Function.prototype
是引擎创建出来的对象,引擎认为不需要给这个对象添加 prototype
属性。
Object
是所有对象的爸爸,所有对象都可以通过__proto__
找到它Function
是所有函数的爸爸,所有函数都可以通过__proto__
找到它Function.prototype
和Object.prototype
是两个特殊的对象,他们由引擎来创建- 除了以上两个特殊对象,其他对象都是通过构造器
new
出来的 - 函数的
prototype
是一个对象,也就是原型 - 对象的
__proto__
指向原型,__proto__
将对象和原型连接起来组成了原型链