关于原型链的思考
以下纯属个人的理解和思考,肯定会有理解有误的地方,如果有新的理解,我会及时修改,也希望大家能多多指正。
原型链存在的意义
构造函数生成实例对象有个缺点:无法共享属性和方法,所以为了解决这个问题,js在构造函数中设置一个prototype属性,把需要实例对象共用的属性和方法放进去。
一张关于原型链的图片
理解这幅图的前提:
- Function、Object、Number、String 看似是数据类型,其实是构造函数。
- Foo是通过Function创造出来的一个函数。
- num是通过Number构造的一个数值。
- [[prototype]]是指向构造函数的原型对象的指针,可以通过proto属性访问。
- Prototype是原型对象,只有函数才有prototype属性。
- 实例的[[prototype]]指向构造函数的prototype。
- 子类的prototype是父类的实例。
思考的点:
- 所有函数(除了Object)的prototype都指向Object的prototype,也就是说所有函数都继承自Object(包括Function)。
- 所有函数(包括Object)都是Function的实例,体现在[[prototype]]指向Function.prototype
- 所以有意思的点是:Function继承自Object,而Object是Function的一个实例。
总结:对象和函数的关系
- 函数与对象之间,绝对不是一种包含和被包含的关系。
“函数是对象”,这句话中的对象,绝对不是一个普通的对象。
所有函数继承自Object,可以认为函数是 Object 的“子类”。(这里的Object也可以读作“对象”,但是它不是我们经常使用的那种普通对象,它是一个构造函数)。
- 而我们平时用到的那些普通对象,是Object的实例。
- 所以函数可以跟Object扯上关系,当最好不要跟普通对象扯上关系。
- 函数的prototype是一个普通对象。