每个函数(构造函数)在创建时,同时函数会自动添加一个prototype的属性,这个属性会指向一个空的object对象,这个空的object对象,因为prototype的属性指向(点出来的)的取名为prototype(原型)对象
function person(){}//普通函数
//undefined
person.prototype
//{constructor: ƒ}//这是一个空构造函数
//person函数是空的,但是window自动给它添加了prototype,打印出来如图所示(圈的那部分)
//这个属性指向的是一个空的object对象(//constructor: ƒ这个后面再说)
function Dog(){}//构造函数
//undefined
let xiaogou = new Dog()
//undefined
Dog.prototype
//{constructor: ƒ}
每个实例对象创建时,同时这个实例会自动添加一个proto的属性,这个属性会指向一个空的object对象,这个空的object对象也叫prototype原型对象
function Dog(){}
//undefined
let xiaogou = new Dog()
//undefined
Dog.prototype
//{constructor: ƒ}
xiaogou.__proto__
//constructor: ƒ}
这个实例对象的proto的属性的地址值就是它的构造函数的prototype的属性地址值,它们指向的是一个prototype原型对象
function Dog(){}
//undefined
let xiaogou = new Dog()
//undefined
Dog.prototype
//{constructor: ƒ}
xiaogou.__proto__
//{constructor: ƒ}
xiaogou.__proto__ === Dog.prototype
//true //它们的地址值都是相等的,指向的是同一个空的object对象
每个函数(构造函数)在创建时,同时函数会自动添加一个prototype的属性,这叫显性属性
每个实例对象创建时,同时这个实例会自动添加一个proto的属性,这叫隐性属性
函数(构造函数)和实例指向的同一个空的object对象,为了好区分是哪个空的object对象,
就叫那个函数(构造函数)的原型对象,
比如上面function person(){}的这普通函数prototype指向的空的object对象,叫person的原型,
function Dog(){}构造函数的prototype指向的空的object对象,叫Dog的原型,
因为xiaogou这个实例对象是Dog这个构造函数创建的,指向同一个原型,
所以xiaogou这个实例对象的隐性原型也叫Dog的原型
构造函数和它的实例对象的共用原型对象也是一个实例对象,实例对象都有会自动添加一个proto的属性,这个属性会指向一个空的object对象,
Dog.prototype.__proto__ //Dog.prototype也是一个实例对象,简称Dog原型实例,这个实例也有__proto__属性
//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
而这个实例对象的proto的属性的地址值就是它的构造函数的prototype的属性地址值,
它的构造函数是Function(系统自带的),每个函数(构造函数)在创建时,同时函数会自动添加一个prototype的属性,这个属性会指向一个空的object对象,这个空的object对象也叫原型对象,因为是Function这个构造函数的prototype属性指向的对象,也叫Function的原型对象
Function的原型对象也是个实例,它的proto指向了 Object的原型对象
Object的原型对象也是一个对象,但是它不是任何构造函数(构造函数的)创建的,它就是所有构造函数(构造函数的)祖宗(最原始那个),所以它的proto的属性是空的
这个函数(构造函数)的原型对象里面的方法属性是公共的,实例对象可以访问,函数(构造函数)也可以访问
一个构造函数可以有多个实例,这样就该构造函数的原型对象作为公共存方法属性的地方
一般存的是公共方法,因为方法时创建要创建一个新的空间,造成内存的浪费,属性创建时在不需要开辟空间,基本数据类型是栈存储,引用数据类型是堆存储
一个实例可以访问创建它的构造函数的原型对象,这个构造函数的原型对象又是其它构造函数的实例,形成这样的链条,叫做原型链,原型链的尽头是Object构造函数的原型对象
Object构造函数是由Function这个构造函数创建(new)的,所以它的proto隐性属性指向了Function显性属性的指向空的object对象,命名为Function原型对象,而Function原型对象最后指向了Object构造函数的原型对象
Object构造函数的显性属性prototype指向的空的object对象,最后指向了Object构造函数的原型对象
所以,只要继承了父类,子类就可以访问到父类的prototype的方法和属性