1. JS继承的设计思想
1.1 生成对象
通常JAVA生成对象是通过new的方式,通过类去生成一个实例对象。但是JS中没有类,于是JS就把new一个类设计成了new一个构造函数,于是构造函数就称为了一个实例对象的原型对象。
2. 为什么要设计原型对象?
以上设计无法共享公共属性。
每new一个对象,生成的是两个不同的对象,属性不共享。
所以要专门一个用来存储对象共享属性的对象,它就叫做「原型对象」。
3. 什么是原型对象
要想让构造函数生成的所有实例对象都能够共享属性,name就给构造函数加一个属性prototype,用来指向原型对象,把所有共享属性方法都放在构造函数的prototype属性指向的原型对象中,不需要共享的属性和方法就放在构造函数中。
JS中函数拥有对象的所有能力,因此也可被当成对象对待,所以函数也可以设置属性。
实例对象一旦通过构造函数创建,就会自动给实例对象赋值上原型对象的共享属性和方法。
4. 对象和函数的原型链关系
声明一个狗的构造函数,定义名字和体重属性。同时有一个prototype属性,指向原型对象。
原型对象里有一个constructor属性,又指回了构造函数。
JS中只要是对象就会有一个内置属性叫做__proto__,指向的是构造函数的原型对象。
而原型对象也是对象,也有__proto__。
所有JS对象都是继承了一个叫做Object的对象。
Objct构造函数的prototype指向的原型对象的__proto__指向的是null。因为Object的构造函数的原型对象是谁?就是它本身,所以Object构造函数的prototype指向的原型对象的__proto__就指向了null。
5. 原型链
JS中所有的function函数都是由Function继承来的,Function构造函数也有__proto__,它直接指向自己的prototype指向的原型对象,也就是说构造函数的__proto__等于构造函数的prototype。
总结
- 所有实例的__proto__都指向该构造函数的prototype(原型对象)
- 所有函数包括构造函数都是Function的实例,所以所有函数的__proto__都指向Function的原型对象。
- 所有原型对象都是Object的实例,所以__proto__都指向Object构造函数的原型对象,而Object构造函数的__proto__指向null
- Function构造函数本身就是Function的实例,所以__proto__指向Function的原型对象。