在开始之前希望我们明确一个概念,大家都知道javascript有一条用于继承的原型链但实际上我觉得《你不知道的javascript》中说的更有道理这与其说是继承不如说是委托
,因为继承是会复制属性的,但js实际上并没有复制属性,它只是创建了一个联系
用于引用时查找。
函数(Function)才有prototype属性,对象(除Object)拥有proto.
1. 构造函数及其原型
当你在创建一个构造函数Person
的时候系统中会自动创建一个它的原型Person.prototype
。因为函数本质上也是对象,所以函数Person
上会自动挂载一个属性prototype
指向它的原型Person.prototype
。如图所示:
image.png
当然,原型在创建的时候也会自动挂载一个属性
constructor
指向它的构造函数,请一定要记住:原型和他的构造函数之间是双箭头的!!!所以有了下面这张图:image.png
2. 实例
一个构造函数函数可以有多个实例,当一个构造函数new
出一个实例person
的时候,这个被创造出来的对象就可以调用构造函数中的所有方法及属性,同时这个实例上会有一个__protot__
的属性指向它的原型对象Person.prototype
。
注意: __proto__
属性目前仍不在标准之中,但现在几乎所有浏览器都支持它
image.png
3. 原型的原型
构造函数的原型并不是凭空出现的,它实际上是被Object
创造出来的,所以
image.png
4. 原型链
那么Object.prototype
的原型对象又是什么呢?大家可以打印一下,我们会发现是null
。那null
又是什么呢?在阮一峰老师的 《undefined与null的区别》中说
null 表示“没有对象”,即该处不应该有值。
所以到此处我们的原型查找就结束了,没有值了。下面这条蓝色的线就是我们最终的原型链。
image.png