我们现在先定义两个构造函数
function Father(){
}
function Son(){
}
共享原型
共享原型就是让Son和Father的原型是同一个。
那么只需要让
Son.prototype=Father.prototype;
如果我们设置Father.prototype.lastName='Yang';
,由于Son与Father共享原型,那么Son和Father生成的对象都可以访问到 lastName 为 Yang 。
但是,由于Son.prototype与Father.prototype都在同一个地址,如果更改Son.prototype中的内容,那么Father.prototype中的内容也会跟着更改。我们想要只为Son的原型里添加东西是做不到的。
那么怎么做到又可以共享原型,又可以在自己的原型上添加自己独有的方法和属性呢?
那就是共享原型的升级版本 圣杯模式啦
圣杯模式
解决方式,看下图
右边生成了一个原型链,原型链的顶端是Father.prototype,Son生成的对象就可以沿着原型链去访问到Father的原型,就能继承Father原型中的内容。
这里F相当与一个中间层,解决了在Son原型里加入东西,会影响到Father的原型这个问题
function inherit(Target,Origin){
function F() {} ;
F.prototype=Father.prototype;
Son.prototype=new F();
}
inherit(Son,Father);
var son=new Son();
var father=new Father();
但是这样子的设定会使得会出现一个问题,当我们查询son.constructor时,返回的是function Father(),是Father的构造函数。这是怎么回事?
下面来找son的constructor:
son.__proto__ --> new F() .__proto__ --> Father.prototype
son对象本身是没有constructor属性的,需要到它的原型中去找。son的原型是new F()也是一个创建出的对象,也没有constructor属性,接着找它的原型,原型就是Father.prototype,而Father.prototypr中的constructor是function Father(){},所以在查询son.constructor时,返回的是function Father(){}。 但我们肯定希望返回的是自己本身的构造器function Son(){},所以我们要在inherit函数中再添加以下内容:
Target.prototype.constructor = Target;
这样圣杯模式就完美啦。