凉水代码

Code Cold Water

导航

JavaScript中的原型(prototype)与继承之精解

Posted on 2010-06-26 16:11  凉水代码  阅读(1641)  评论(0编辑  收藏  举报

原形与原型的区别:

prototype的意思是原型,至于为什么叫原型,而不叫原形曾一度困惑了我好久,后来搜索才有所了解:

原形:本来的形状,原来的形态 
原型:原始的模型,特指文学艺术作品中塑造人物形象所依据的现实生活中的人。 
区别 原形是指事物的本身; 原型是事物的所指; 

我们先看一下JavaScript中的原型:JavaScript中的原型就是他的构造函数的prototype属性,这个属性是一个对象,对象中只有一个叫做construct的属性,construct属性就是prototype关联的那个构造函数.

 

我们需要对这句话进行一下分析:原型是构造函数的一个属性,名字叫做prototype.是一个对象,他有一个construct属性指向那个构造函数。

OK.依据分析,我们来看下什么是原型.

假设有一个类: 

function ClassA(x){
  
this.x = x; //实例属性必须用this.修饰 (这很重要)
}

他的原型是是一个叫做prototype的对象。 

ClassA.prototype = new Object();

 有一个叫做construct的属性指向那个构造函数

ClassA.prototype.construct = ClassA;

 

类属性:类属性是一个和类关联的属性,而不是和每一个实例关联的属性。

根据定义,原型是一个类属性,这很重要

 

 JavaScript 继承 特性:继承作为一个查找属性的过程自动发生。

谈到继承,当然是谈实例,

例:

var a = new ClassA(10);

要读取a.x属性时,先查找ClassA的实例属性中有没有x属性,发现有,返回x.

当要读取a.y属性时,先查找ClassA的实例属性中有没有y属性,没有,到ClassA.prototype中查找,也就是new Object()对象中找。也没有,因为 ClassA.prototype是一个Object对象,所以向Object.prototype中查找。还是没有,于是返回一个错误。y未定义。

 

我们现在创建一个ClassB类,让其继承ClassA:

首选创建ClassB类

function ClassB(y){
this.y = y;
}

  

 让ClassB继承ClassA.也就是说ClassB要拥有ClassA的属性。根据继承的性质,ClassB的属性有可能从其prototype属性中获得。所有我们让ClassB的prototype是一个ClassA实例。

ClassB.prototype = new ClassA();

ClassB类就有了 ClassA的属性,于是我们改下 ClassB的构造方法,让 ClassA的x属性能在 ClassB中进行赋值 

functon ClassB(x,y){
ClassA.call(
this,x);
this.y= y;
}

ClassB就有 ClassA的x属性,但是 ClassA中的那个c属性现在就永远无法访问到了。而且那个x还没有实际有意义的值。算是一个浪费了。

或许我们可以通过ClassB.prototype.x来访问。因为prototype是一个类属性,如果改变了其中的值,就是改变了类属性的值,通常这是不好的,为了不浪费,所以我们将他的prototype中的x属性删除

delete ClassB.prototype.x

 

因为现在 ClassB.prototype.construct属性仍然是从 ClassA.prototype.construct中获得到,我们希望继承是拥有自己的构造方法。所以我们将这个值改为 ClassB
 

ClassB.prototype.construct = ClassB;

 

 

好,到现在,继承完在。做一下总结:

继承的过程:

1.在ClassB的构造中调用 ClassA.call(this,x); 目的是让ClassB有x属性值。

2.delete  ClassB.prototype.x;   目的是为了不浪费空间。
3.ClassB.prototype.construct =  ClassB; 目的是把自己的构造改回来。

4.子类的实例属性无法从父类继承,继承通常是为了继承父类的方法。