1.冒充继承
- 使用构造函数的技术或者对象冒充的技术,解决引用共享和父类无法传参的问题。
- 没有原型。
function Box(age){
this.name=['zhang','wang','li'];
this.age=age;
}
function Desk(age){
Box.call(this,age);
}
var desk=new Desk(200);
2.组合继承
- 使用原型链+借用构造函数的模式解决没有原型的问题。
- 出现父类被调用两次并且,子类原型上的属性值为undefined
function Box(age){
this.name=['zhang','wang','li'];
this.age=age;
}
Box.prototype.run=function(){ return this.name+this.age; }
function Desk(age){
Box.call(this,age);
}
Desk.prototype=new Box();
var desk=new Desk(100);
3.原型式继承
- 解决不通过new 父类的方式赋给子类的原型,将父类的原型赋值给一个新的函数的原型,即new新的函数=new父类。
- 这种继承借助原型并基于已有的对象创建新对象。
- 缺点,每次都要创建新函数。
function Ball(_a){
Box.call(this,_a)
}
function F() {};
F.prototype = Box.prototype;
Ball.prototype = new F();
Ball.prototype.constructor = Ball;
let b = new Ball(10)
4.寄生式继承
- 将原型式+工厂模式结合而来,目的是为了封装创建对象的过程。
function extend(subClass, supClass) {
function F() { }
F.prototype = supClass.prototype;
var proto = subClass.prototype;
subClass.prototype = new F();
var names = Object.getOwnPropertyNames(proto);
for (var i = 0; i < names.length; i++) {
var desc = Object.getOwnPropertyDescriptor(proto, names[i]);
Object.defineProperty(subClass.prototype, names[i], desc);
}
subClass.prototype.constructor = subClass;
subClass.prototype.superClass = supClass.prototype;
if (supClass.prototype.constructor !== supClass) {
supClass.prototype.constructor = supClass;
}
}
function Ball(_a) {
this.superClass.constructor.call(this, _a);
}
Ball.prototype.play = function () {
this.superClass.play.call(this);
console.log("end");
}
Object.defineProperty(Ball.prototype, "d", {
value: 20
})
extend(Ball, Box);
var b = new Ball(10);
console.log(b);