1.传统形式 - 原型链
缺点:过多的继承了没用的属性
Grand.prototype.lastName = 'Jack'
function Grand () {}
var grand = new Grand ()
Father.prototype = grand
function Father () {
this.name = 'hehe'
}
var father = new Father ()
Son.prototype = father
function Son () {}
var son = new Son()
2.借用构造函数
缺点:
- 不能继承构造函数的原型
- 每次构造函数都会多走一个函数
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
function Student(name, age, sex, grade) {
Person.call(this, name, age, sex)
this.grade = grade
}
var student = new Student()
3.共享原型
缺点:不能随便改变自己的原型(会连着继承的父类一起改变)
Father.prototype.lastName = 'Jack'
function Father () {}
function Son () {}
Son.prototype = Father.prototype
var son = new Son()
将上述代码封装一下
Father.prototype.lastName = 'Jack'
function Father () {}
function Son () {}
function inherit(Target, Origin) {
Target.prototype = Origin.prototype
}
inherit(Son, Father)
var son = new Son()
4.圣杯模式(常用)
共享原型继承如下图,子类改变也会影响父类
在共享原型的方法上,如果构建一个中间层,如下图:
这样就可以避免共享改变父类的问题,代码如下:
Father.prototype.lastName = 'Jack'
function Father () {}
function Son () {}
function inherit(Target, Origin) {
function F () {}
F.prototype = Origin.prototype
Target.prototype = new F()
}
inherit(Son, Father)
var son = new Son()
但是,又有了新的问题:son.constuctor指向了function Father() {}
指向紊乱了
解决方法:Target.prototype.constuctor = Target
更好的话,再加上超级父类:Target.prototype.uber = Origin.prototype
完整代码如下:
Father.prototype.lastName = 'Jack'
function Father () {}
function Son () {}
function inherit(Target, Origin) {
function F () {}
F.prototype = Origin.prototype
Target.prototype = new F()
Target.prototype.constuctor = Target
Target.prototype.uber = Origin.prototype
}
inherit(Son, Father)
var son = new Son()
var father = new Father ()