原型
要先建立构造函数,构造函数的 prototype 属性会自动指向原型对象。
在创建实例后,可以修改 prototype 对象中的属性,但不可以重写整个原型(开始没有定义,再实例创建后给 prototype 添加属性
构造函数、原型和实例的关系
- 每个
构造函数
都有一个原型对象(原型 prototype) 原型
有一个constructor
属性指回构造函数实例
有一个内部指针[[Prototype]]
指向原型- 原型上的所有属性在实例间共享
- 实例上添加同名属性会遮蔽原型上的属性
如图,展示了 Person 构造函数、Person 的原型对象和 Person 现有的两个实例之间的关系。Person.prototype
指向原型对象
,Person.prototype.constructor
指回构造函数
。
原型对象中包含constructor
属性和其他后来添加的属性。Person 的两个实例 person1 和 person2 都只有一个内部属性指回Person.prototype
,而且两者与构造函数没有直接联系。
实例的属性和方法
虽然两个实例都没有属性和方法,但是它们person1.sayName()
可以正常调用,这是由于对象属性查找机制,通过对象访问属性时,会按照这个属性的名称开始搜索,先搜索对象实例本身,如果有则返回对应的值,如果没有找到这个属性,则搜索会沿着指针
进入原型对象,在原型对象上找到属性后,再返回对应的值。
原型链
基本构想是:实例
指向 原型
,而 原型
是另一个 原型
的 实例
,意味着这个原型
的本身有一个内部指针指向另一个原型
(继承的原型),相应的另一个原型
也有一个指针指向另一个 构造函数
(它自己的),这样实例
和原型
之间就构造了一条 原型链。原型链
扩展了原型搜索机制,读取实例上的属性时,先在实例上搜索,再搜索它继承的原型,再通过原型链 继承
后,搜索就可以继承向上,顺着 原型链
向上搜索其他的原型。
默认情况下,所有引用类型都继承Object
,任何函数的默认原型都是一个Object
的实例。
这意味着这个实例有一个内部指针指向这个Object.prototype
,所以原型链的顶端还有Object
, Object.prototype
是null
。