注意:
- 每个类都有一个prototype静态属性(对象实例不能访问),该属性指向一个标识类的对象(原型对象)
- 原型对象上定义了一些内部属性用来描述该类,其中就包括该类的基类的信息。基类也有相同的构成,因此js解释引擎就知道类的基类,基类的基类构成的一个链条。因为原型对象里描述基类信息的内部属性为[Prototype],所以该链条也被称为原型链。(原型对象里有描述该类基类信息的属性为[Prototype])
- 原型链的源头是Object的原型对象该对象的内部属性[Prototype]为的值是null。
- 类的实例隐式的包含有对自身原型对象的引用__proto__。
原型链的根源
一个类定义时,它有原型对象(有多个内部属性用来描述类的信息),其中两个内部属性是[Prototype]和[Class].,对于那些有构造函数的类来说,构造函数就是他的原型对象。
- 内部属性[Prototype]
表示该类的父类的原型对象,一般使用属性__proto__来访问,IE封闭了该属性,其它的浏览器可以访问。
注意区分内部属性和静态属性prototype,其首字母大小写有别。
- [Class]
表示类名,是一个字符串。所有内部JavaScript类的[Class]属性值:
"Arguments","Array","Boolean","Date","Error","Function","JSON","Math","Number",
"Object","RegExp","String"
例如:内部类Array定义时:
{ Prototype:Object的原型对象; Class:"Array"; }
运行时,javaScript解释引擎通过[Class]就知道该类的名称信息,通过[Prototype]就能找到该类的父类的原型对象信息。每个内部类原型对象的内部属性[Prototype]的值都是Object的原型对象(因为它们都直接继承自Object)。因为Object类是根类,所以它的原型对象为:
{ Prototype:null; Class:"Object"; }
总结:内部属性[Prototype]表示了继承关系,也就是原型链。
访问内部属性[Prototype]
看下边的等式:
Array.prototype.__proto__===Object.prototype; //__proto__下划线为双下划线才对。
(new Array()).__proto__.__proto__===Object.prototype;// 当实例应用__proto__时,返回对当前实例所表示类的原型对象的引用。
(new Array()).__proto__===Array.prototype;
Object.prototype.__proto__===null;
//再来看看自定义类:
function People(){}
People.prototype.__proto__===Object.prototype;
//同样:如果存在自定义类的子类Child
function Child(){}
Child.prototype=new Person();//作为Peoson类的子类
Child.prototype.__proto__===People.prototype;
Child.prototype.__proto__.__proto__===Object.prototype;
prototype的作用
实现继承和分享属性都是原型链的组成部分。原型对象里有对象所有的属性和方法,因此可以通过此属性给类添加属性(实例共享的只有一份),这就可以理解继承原理。
function People(){}
function Child(){}
Child.prototype=new Person();//作为Peoson类的子类
因为Perple实例隐含有Perple类的原型对象的引用,因此当执行这个赋值操作时,JavaScript解释引擎可以获取People实例的原型对象属性值,然后更改Child的内部[Prototype]。现在Child的内部属性的定义:
{
Prototype:People的原型对象;
Class:"Child";
}
使用Object.getPrototypeOf(obj)方法获得指定对象的Prototype属性,即获得实例的原型对象。替代__proto__,IE也支持
Object.getPrototypeOf(new Array())===Array.prototype;