本文实例讲述了JavaScript寄生组合式继承。分享给大家供大家参考,具体如下:
其实《JavaScript高级程序设计》这本书中已经有完整代码了,只要把代码读懂就知道这个继承是怎么回事。
首先,在js中,给对象定义属性有两种方式:
//通过执行构造函数设置属性 function A(){ this.a = 1; } //通过原型设置属性 A.prototype.b = 1;
所以:
一个类Sub要继承另一个类Super,需要继承父类的prototype下的属性,还要执行一下父类的构造函数。
即一个类Sub要继承另一个类Super,既要通过原型链实现对原型属性和方法的继承,又要通过在子类构造函数内调用父类构造函数实现对实例属性的继承。
1. 继承prototype下的属性
上面可以看到,Super类的prototype下的属性是没有被继承的,因此下面还需要继承这一部分。
直接「=」肯定不行,因为Sub.prototype中修改属性后,不能影响Super.prototype里面的对象,即不能Sub.prototype=Super.prototype
。
首先写一个创建对象副本的方法
function object(o){ function A(){} A.prototype = o var ox = new A() return ox }
上面的函数得到的对象ox,拥有了对象o的全部属性(在原型链上),而修改ox的属性,不会影响到o,相当于把o复制了一份。
原型式继承就是上面的“object”函数,在很多类库源码中都能发现它的身影
简单而言,原型式继承就是不用实例化父类了,直接实例化一个临时副本实现了相同的原型链继承。(即子类的原型指向父类副本的实例从而实现原型共享)
tips:总所周知,原型链继承是子类的原型指向父类的实例从而实现原型共享,而原型式继承是子类的原型指向父类副本的实例从而实现原型共享。
ECMAScirpt 5通过新增Object.create()
方法规范化了原型式继承。
使用object方法,就可以将Super.prototype的属性「复制」到Sub.prototype上了,当然这儿还需要修正一下constructor的指向。
function inherit(subType,superType){ var prototype=Object.create(superType.prototype); prototype.constructor=subType; subType.prototype=prototype; }
2. 分别执行父类和子类的构造函数,继承这部分下的属性:
//父类 function Super(){ this.sss=1 } //子类 function Sub(){ //arguments是Sub收到的参数,将这个参数传给Super Super.apply(this, arguments) } //实例 sub = new Sub()
Super.apply(this, arguments)
这一句,将Super类作为一个普通函数来执行,但是Super类的this被换成了Sub类的this,Sub收到的参数也传给了Super