原形与原型的区别:
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.子类的实例属性无法从父类继承,继承通常是为了继承父类的方法。