1. function Person() {
    2. }
    3. Person.prototype.name = 'KK';
    4. var person1 = new Person()
    5. var person2 = new Person()
    6. console.log(person1.name) //kk
    7. console.log(person2.name) //kk
    8. console.log(Person === Person.prototype) //false
    9. console.log(Person.prototype.constructor === Person) //true
    10. console.log(person1._proto_ === Person.prototype) //false
    11. console.log(person1 === Person.prototype)//false

    什么是原型?什么是原型链?

    当创建一个函数(除了bind函数外)时,这个函数就包含了一个prototype的属性,它指向由该构造函数创建的实例的原型(指向实例的原型,Person指向Person.prototype)。

    当创建一个对象(除了null)时(每一个对象都会与之相关的原型对象相关联),这个对象会包含一个proto的属性,它指向对象的原型(person1、person2都指向Person.prototype)。

    对象的原型(Person.prototype)也是一个对象,它内部包含一个constructor属性,这个属性指向构造函数(Person)。既然原型是对象,也可以通过Object(所有对象都继承自Object类)来创建:

    1. var obj = new Object()
    2. obj.name="yy"
    3. console.log(obj.name) //yy

    此时实例obj的原型对象是通过Object的构造函数创建的。

    分别打印最上面例子的Person.prototype、Person.prototype.constructor、person1.proto、person1.constructor、Person、Person.constructor的值分别为:

    Person.prototype和person1._proto_:
     一个对象里面包含:constructor为Person函数的属性、_proto_为Object的对象。
    Person.prototype.constructor和person1.constructor、Person:
    一个函数:值为Person函数。
    Person.constructor:
    一个函数:值为Function函数。
    

    image.png

    image.png

    image.png

    image.png

    可以看到Person.prototype里面不仅仅包含了指向Person构造函数的constructor属性,还包含了一个指向Object对象的对象proto。Js中所有的对象(Array、Function、Date等等)都是基于Object创建(函数也是一个对象),都是Object的实例,所以对象中的proto必定指向Object构造函数创建的实例的原型(Object.prototype,或者说Object类型的原型对象)。
    对象上的protoproto属性构成了原型链。

    Object是最顶层的一层对象,其原型上没有对象,即Object.prototype的指向为Null。
    image.png

    构造函数、Object、原型与Function的关系?
    当打印Person时,打印的是 function Person() {},我们知道,函数名只是函数的一个引用。
    函数也是一个对象,那么通过这个对象就能读取到constrctor的属性。
    当打印Person.constructor时,打印的是Function() {}。可以知道function Person() {}是构造函数Function的实例。
    那么就应该有Person.constrctor等于Function,

    function Person() {
    
    }
    
    console.log(
      Function.prototype , Person.constructor,
      Function, Function.constructor,
      Function.prototype.constructor
    ) 
    //ƒ () { [native code] }  ƒ Function() { [native code] } 
    //ƒ Function() { [native code] } ƒ Function() { [native code] }
    //ƒ Function() { [native code] }
    
    console.log(Person.constructor === Function) //true
    
    console.log(Person.constructor === Function.constructor)//true
    

    看如下图搞清楚Function、Object、实例、原型之间的关系:
    image.png

    这里有一个关于Function很关键的一个点