原型(对象属性):
Jacascript 规定,每一个函数都有一个 prototype 对象属性,指向另一个对象(原型链上面的)。prototype (对象属性)的所有属性和方法,都会被构造函数的实例继承。这意味着我们可以把那些不变(公用)的属性和方法,直接定义在 prototype 对象属性上。
prototype 就是调用构造函数所创建的那个实例对象的原型(__proto__)。
prototype 可以让所有对象实例共享它所包含的属性和方法。也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。
原型链:
实例对象与原型直接的连接,叫做原型链,proto(隐式连接)。
JS 在创建对象的时候,都有一个叫做 __proto__ 的内置属性,用于指向创建它的函数对象的原型对象 prototype。
内部原型(__proto__)和构造器的原型(prototype):
1. 每个对象都有一个 __proto__ 属性,原型链上的对象正是依靠这个属性连接在一起。
2. 作为一个对象,当你访问其中的一个属性或方法的时候,如果这个对象中没有这个方法或属性,那么 JS 引擎将会访问这个对象的 __proto__ 属性所指向上一个对象,并且在那个对象中查找指定的方法或属性,如果不能找到,那么就会继续通过那个对象的 __protp__ 属性指向的对象进行向上查找,直到这个链表结束。
__proto__ 和 prototype 的区别:
先了解三个对象类型:Object类型,普通对象类型,函数类型。
1. Object 与 普通类型为同一级别,函数类型比其他类型低一级别。
2. 函数类型有两个属性(即 __proto__ 和 prototype)。此函数分别继承这两个属性。prototype 为对象类型,而 __proto__ 为函数类型。


3. 而普通对象类型只有 __proto__ 属性,该属性为对象类型。


4. 由于 Object 为函数类型,故其有 prototype 和 __proto__ 属性。且与函数类型一样,prototype 为对象类型,__proto__ 为函数类型。


- 比较同一级别的 Object 类型与普通对象类型:
1. Object.prototype = 普通对象类型的__proto__
由于普通类型只有 __proto__ 属性,且其为对象类型,以及普通类型与Object为同一级别 ,故比较 普通类型的 __proto__ 属性是否与 Object 类型的 prototype 属性相同。

2. Object.prototype 对象类型为最高一级,向上就无 prototype 和 __proto__ 属性


由第一点知:Object.prototype = 普通对象类型的__proto__, 故普通类型的__proto__也为最高级别。
- 普通类型与函数类型的区别:
函数类型的 prototype 对象类型与 普通对象类型为同一级别。(即函数类型比普通对象类型低一级别)
由于函数类型的 prototype 为对象类型,故可以与普通对象类型进行比较,又由于函数类型里有参数,属性等,故函数类型的 prototype 属性并不与普通类型完全相同,故不能用:
函数.prototype == 普通对象类型
但我们可以用其上一级来比较:(由于对象类型只有 __proto__ 属性)
函数.prototype.__proto__ == 普通对象类型.__proto__


- 函数类型与Object类型:
与函数类型和普通对象类型类似,但由于Object为函数类型,故其还有一个特性。
由于__proto__ 为函数类型,故可以判断:Object.__proto__ == 函数类型.__proto__ 是否相同。


总结:
树状图如下:
