1、名称对应
prototype:原型
__proto__:原型链(链接点)
2、从属关系
prototype :是函数的一个属性,它的类型是对象{}。
__proto__ :是对象Object的一个属性,它的类型也是对象{}。
对象的__proto__保存着该对象的构造函数的prototype。
一个函数的原型的__proto__全等于Object.prototype。
原型链的最顶层是Object.prototype。
3、实例验证从属关系
3.1、有一个函数Test()
function Test(){}由于函数都有prototype属性:
console.log(Test.prototype);//构造函数Test()有prototype属性得到输出结果:

3.2、实例化Test()函数的对象
let test = new Test();实例化test对象,由于对象都有__proto__属性:
console.log(test.__proto__);//由构造函数Test()构造出来的对象有__proto__属性得到输出结果如下:

由于对象的__proto__保存着该对象的构造函数的prototype,那么构造方法的prototype应该完全等于对象的__proto__:
console.log(Test.prototype === test.__proto__);//true得到如下输出结果:

由于一个函数的原型的__proto__全等于Object.prototype:
console.log(Test.prototype.__proto__ === Object.prototype);//true得到输出结果:

由于原型链的最顶层是Object.prototype,所以Object.prototype不会再有__proto__:
console.log(Object.prototype.__proto__);//null得到输出结果:

4、原型链继承
在Test()构造函数中新增属性"a:1"、在Test()方法的原型上新增"b:2"、在Object的原型上新增"c:3":
function Test(){
this.a = 1;//构造方法中新增属性a
}
Test.prototype.b = 2;//构造方法的原型上新增属性b
Object.prototype.c = 3;//在Object的原型上新增属性c
let test = new Test();
console.log(test);输出结果:

输出这三个新增的属性:
console.log(test.a);
console.log(test.b);
console.log(test.c);结果:

这个原型链的结构如下:
test:{
a:1,
__proto__:Test.prototype = {
b:2
__proto__:Object.prototype = {
c:3
}
}
}以一个对象为基准,以
__proto__为链接,一直到Object.prototype为止的这个链叫做原型链。
如上面的例子:在自己的这个对象test中没有找到属性b就会沿着原型链继续向上找,直到在Test.prototype上找到属性b;c属性也是一样,在对象自身和Test.prototype都没有找到,继续向上找最终在Object.prototype中找到属性c;这就是原型继承;也就是为什么test.b和test.c能够输出正确的值的原因。

在任意一层找到了目标属性,都不会再继续向上一层查找,例如:在test对象本身有属性b,
Test.prototype上也有属性b。此时访问test.b返回的是test对象本身的属性b,而不是Test.prototype上的属性b。
5、Object和Function的特殊性
Object和Function既是函数又是对象。
5.1、Function
以下的Test方法其底层的构造方法是Function 即:const Test = new Function();
function Test(){
this.a = 1;
}Test既是对象又是函数,那么Test就有__proto__属性;Function是它的构造函数,因此Function就有原型prototype,并且Test.__proto__保存的就是Function.prototype。
因此:
console.log(Test.__proto__=== Function.prototype);输出:true。
Function既是函数又是对象,那么Function也有__proto__和prototype。
输出:
console.log(Function.__proto__);
console.log(Function.prototype);结果:

验证它们是否相等:
console.log(Function.__proto__=== Function.prototype);输出:true,说明它们完全相等。
结论:Function的
__proto__本身就指向它自己的prototype。
5.2、Object
Object既是对象又是函数。说明Object本质上也是由Function构造的。
因此:
console.log(Object.__proto__ === Function.prototype);//true又因为Function的__proto__指向它自己的prototype,所以:
console.log(Object.__proto__ === Function.__proto__);//true6、判断对象中某个属性是否存在的方法
6.1、判断对象中是否存在某个属性
obj.hasOwnProperty('属性名')方法用来判断对象中是否存在某个属性,该方法返回一个布尔值,属性存在返回true,不存在返回false。
console.log(test.hasOwnProperty('a'));//true
console.log(test.hasOwnProperty('b'));//false,因为b属性在Test.prototype上
console.log(test.hasOwnProperty('c'));//false,因为c属性在Object.prototype上6.2、判断对象原型链上是否存在某个属性
console.log('a' in test);//true
console.log('b' in test);//true 自Test.prototype上继承而来
console.log('c' in test);//true 自Object.prototype上继承而来7、constructor与实例直接的关系和特性
7.1、constructor属性
输出constructor:
console.log(test.constructor);结果:

说明contrustor就是实例化对象的构造函数。
console.log(test.constructor === Test)//true7.2、对象的constructor可以被修改
function Test2(){
this.a = 222;
}
test.constructor = Test2;//原本为Test()改成Test2()
console.log(test);