1.每个构造函数身上都有一个 prototype 原型,它的身上一般用于定义并存放该构造函数公用的方法,让每个由该构造函数所实例化出来的实例对象都可以使用 prototype 原型身上的方法,避免内存的浪费。
2.原型对象 prototype 身上存在一个 constructor 属性,该属性指向创建该实例对象的构造函数,即表明该实例对象是由哪个构造函数创建出来的。
3.每个对象身上都有一个 __proto__属性,我们称它为 对象原型,该对象原型指向构造函数身上的prototype原型对象。
4.因为 prototype 也是一个对象,所以它也有 __proto__ 对象原型,它再往上指,指向Object的 prototype原型对象。
5.Object 的 prototype 是Object的构造函数身上有的,该 prototype 的 constructor 又指向Object构造函数(constructor主要就是用来指明该实例对象是由哪个构造函数实例化来的)
6.Object 的 prototype 是一个对象,它也有 __proto__属性,它指向为 null 即原型链的尽头。
总结:原型链其实就是一套查找规则,当想要调用对象身上的某个方法时,会先在该对象自身去寻找,如果找不到,就通过 __proto__属性去构造函数的prototype原型对象身上去找,再找不到就通过 该 prototype 的__proto__接着往上找,直到找到该方法或者找到null结束。