原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性。
一、原型
在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个”[Prototype]”内部属性,这个属性所对应的就是该对象的原型。
“[Prototype]”作为对象的内部属性,是不能被直接访问的。所以为了方便查看一个对象的原型,Firefox和Chrome中提供了proto这个非标准(不是所有浏览器都支持)的访问器(ECMA引入了标准对象原型访问器”Object.getPrototype(object)”)。在JavaScript的原型对象中,还包含一个”constructor”属性,这个属性对应创建所有指向该原型的实例的构造函数。
二、规则
在JavaScript中,每个函数 都有一个prototype属性,当一个函数被用作构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给所有对象实例(也就是设置 实例的__proto__
属性),也就是说,所有实例的原型引用的是函数的prototype属性。(只有函数对象才会有这个属性!)
var 对象 = new 函数() 对象.proto === 对象的构造函数.prototype
// 推论
var number = new Number()
number.proto = Number.prototype
Number.proto = Function.prototype // 因为 Number 是 Function 的实例
var object = new Object()
object.proto = Object.prototype
Object.proto = Function.prototype // 因为 Object 是 Function 的实例
var function = new Function()
function.proto = Function.prototype
Function.proto == Function.prototye // 因为 Function 是 Function 的实例!
原型链
因为每个对象和原型都有原型,对象的原型指向原型对象,
而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。
所有原型链的终点都是Object函数的prototype属性,因为在JavaScript中的对象都默认由Object()构造。Object.prototype指向的原型对象同样拥有原型,不过它的原型是null,而null则没有原型。