1、prototype和__proto__,constructor的关系
假设现在定义两个类来替代构造函数
class Parent {
constructor(name){
this.name=name;
}
}
class Child extends Parent {
constructor(name,age){
super(name);
this.age=age;
}
}
const child = new Child("xiaohua",18)
这里可以看到每一个对象都会有__proto__([[Prototype]])属性,且该属性始终又constructor和他自己的__proto__属性
这里验证出 所有实例的构造函数和构造函数的prototype属性的构造函数都指向构造函数自身,关键信息: 构造函数.prototype的构造函数===构造函数,也就是说函数自身的prototype是自己构造的,甚至Function本身的构造函数也是Function。
结论: 所有构造函数的实例对象的上一层原型链__proto__都是相等的且都指向实例对象的构造函数的prototype属性,child.proto === child.constructor.prototype,也就是
实例对象. __proto __ === 构造函数.prototype
结论:所有函数的prototype的上一层原型链__proto__都指向它的继承函数的prototype属性,直到找到Object.prototype的原型为null才停止,值得注意的点是,所有函数(包括Function本身)当没有继承函数时,它的prototype的默认原型__proto__都指向Object.prototype。
结论: 函数的__proto__属性指向自己的继承函数,当没有继承函数时,它继承自一个匿名函数,而这个匿名函数又继承自Object.prototype,最终指向null,值得注意的是Function. __ proto __ === Function.prototype === Object.__ proto __===匿名函数,所以函数继承关系为
构造函数<继承函数<匿名函数(Function.prototype)<Object.prototype<null
对象继承关系为
实例对象<构造函数.prototype<继承函数.prototype<Object.prototype<null
由上面结论可得,由Object.prototype定义的属性可以被任何继承的对象、函数继承,而绑定在Function.prototype的属性不能被实例对象访问。Object和Function访问属性时找不到会去找对应的__proto__属性,而他们的__proto__都等于Function.prototype本身,所以都能访问到值。而构造函数会依次继承自Function.prototype和Object.prototpe,所以能访问,而实例对象child只继承自Object.prototype,虽然继承Child和Parent函数的prototype属性,但是Parent.prototype并不继承自Function.prototype,所以访问不到绑定在Function.prototype上的值