js原型

原型链的根源

当一个类定义时,它就有原型对象(prototype object),原型对象必须有多个内部特定属性来表示类的特性。

prototype的作用——原型链的实现

每一个类又有一个prototype属性标识类的原型对象,该属性是静态属性,它有两个作用,一个是实现继承,一个是分享属性。所以实现继承和分享属性是原型链的组成部分。

1、实现继承

使用prototype静态属性来实现继承是通过改变[Prototype]的值来实现的([Prototype]表示该类的父类的原型对象,注意是父类的原型对象,一般使用_proto_来访问)。

例:

js原型
function Person(){}
function Child(){}
js原型

它们分别有下面的内部属性

js原型
{
  Prototype:Object原型对象
  Class:Person  [Class]表示类名    
}
{
  Prototype:Object原型对象
  Class:Child
}
js原型

假如Person和Child是继承关系,那么就可以用下面的代码来实现:

js原型
Child.prototype=new Person();
js原型

因为Person实例也隐式包含了Person类的内部属性[Prototype],因此当执行这个赋值关系时,javascript解释引擎可以获取Person实例的[Prototype]属性值,然后改变Child的[Prototype]属性值,于是存在下列关系:

js原型
{
  Prototype:Person
  Class:Child
}
js原型

2、分享属性

在创建类的实例时,该实例隐式包含有对自身原型对象的引用,因此实例中也包含有[Prototype]属性。

一个类的所有属性都定义在原型对象上面,当类的实例访问一个属性时,javascript解释引擎就会去原型对象上查找属性,然后执行。

例:

js原型
function GrandFather(){
   this.g1="";
   this.g2="";
}
function Father(){
   this.p3="";
   this.p4="";
}
function Child(){
   this.C5="";
}

Father.prototype=new GrandFather();
Child.prototype=new Father();
js原型

那么在实例化GrandFather时,这个实例隐式包含有自身内部属性[Prototype]的值,该值包含有GrandFather类属性的描述;同样在实例化Father时,这个实例隐式包含有自身内部属性[Prototype]的值,该值包含有Father类属性的描述;在实例化Child时,该实例包含有自身内部属性[Prototype]的值,该值包含有Child类属性的描述。

如果Child的实例调用一个属性时,那么就会按照下面的步骤:

(1)首先查找Child是否存在指定属性,如果存在就执行,如果不存在就查找该实例包含的自身内部属性[Prototype]的值,查到原型对象是Father实例,执行下一步。

(2)查到Father是否存在指定属性,如果存在,就执行该属性,如果不存在,就查找该实例包含的内部属性[Prototype]的值,查到原型对象是GrandFather实例,执行下一步。

(3)查找GrandFather是否存在指定属性,如果存在就执行,如果不存在,就查找该实例包含的内部属性[Prototype]的值,查到原型对象是Object实例,执行下一步。

(4)查找Object是否存在该属性,如果存在就执行,如果不存在,就会返回undefined,因为Object就是原型链的尽头。

因为方法就是类型为function的属性,因此,这一过程,同样适用于方法。

总结:

每一个类都有一个prototype属性,这是一个静态属性,该属性包含了标识该类的一个对象,这个对象称为原型对象。

在原型对象上定义了一些属性用于描述该类,其中就包含了该类的基类信息,通过信息,javascript解释引擎就可以知道该类的基类,同时基类也有相同的构成,因此javascript就可以知道基类的基类,这就建立了一个链条,因为描述基类信息的内部属性是prototype,所以该链条叫原型链。

原型链的尽头是Object的原型对象,该对象的原型对象[Prototype]的值是null。

js原型,布布扣,bubuko.com

js原型

上一篇:百度UEditor开发案例(JSP)


下一篇:PHP中你应该知道的require()文件包含的正确用法