解析一下寄生组合式继承使用的原因。因为其他的继承方式要么就是函数无法复用(就是每创建一个新的实例,创建其中的方法的时候,就相当于又创建了一个新的对象,但是这种方法创建的机制其实是一样的,属性时简单值的就无所谓),因此用原型来继承要用的方法的话,就不必每次创建方法了,只需要在使用的时候搜索到原型上的此种方法就可以使用了。
因此用构造函数加原型的模式来继承,一个让实例继承后有自己独立的属性,作修改不会影响其他的值,然后有共有的属性和方法,可以做到函数复用。(但是在重写原型的时候属性方法都做了继承,只是同时在创建新对象的时候又重新写了一遍现在原型中有的属性,因此修改的话实际修改的是新实例已经有的属性,但是如果删除了在写就会改变原型的属性了,这是为什么实例也有各自独立属性的原因)
function Sub(name,age){
Sup.call(this.name); //这里会在创建新的实例的时候写入一遍Sup()构造函数里所拥有的属性和方法
this.age=age;}
Sub.prototype=new Sup();//然后重写原型,原型上也有这些属性和方法
重写原型继承他的方法和属性,但是上方在子类型构造函数我们调用超类型构造函数重写了他的属性,因此在Sub()的新实例中就有了Sup()已经有的属性了,所以修改实例中的某一个属性并不会影响到Sup()本身。而其实要这么做的原因在于Sup.prototype.say=function(){//代码}
这一行代码, 这样方法就可以通过Sup的原型传递给新的实例了,不用写在Sup构造函数里,但完成了函数的复用,也让实例有了自己的属性和方法。
但是这时问题又来了,每次都要调用两次超类型构造函数,就是Sup,一次是重写原型,一次是子类型构造函数内部,于是在子类型调用的时候所有实例就有了超类型的属性和方法,我们需要的只是为了让函数复用定义在Sup原型上的方法,就像上文的say(),所以我们只需要超类型原型的一个副本就可以,我认为可以 Sub.prototype=Object.create(Sup.prototype)即可,不过高程给了一个可以随时调用的方法,
function inheritPrototype(Sub,Sup){
var prototype=Object.create(Sup.prototype);//创建对象
prototype.constructor=Sub;//增强对象 因为上面代码重写了新创建对象原型的值,constructor属性继承了Sup原型的值指向了Sup,因此重写
Sub.prototype=prototype;//指定对象,子类型构造函数继承了超类型构造函数原型中的方法从而可以调用
}
这样就不必在指定子类型的原型的时候调用超类型构造函数,提高了效率。
网友评论