javascript不是一门基于类的语言,因此没有一个确定的继承的方法。(es6提供了class和extend关键词,用来实现像java这类强类型语言的继承的样子,实际上是一种语法糖。)虽然说js没有类,但是要实现继承却有很多种方法。主要分为类式继承及现代继承(就是不考虑像有类一样去继承)。
要实现的继承效果是:
//parent构造函数
function Parent(name) {
this.name = name || 'Adam';
}
//给原型增加方法
Parent.prototype.say = function () {
return this.name;
};
//空的child构造函数
function Child(name) {}
//继承
inherit(Child, Parent);
类式继承
类式继承1——默认模式
function inherit(C, P) {
C.prototype = new P();
}
var kid = new Child();
kid.say(); // "Adam"
当new Parent()来创建一个对象时,这个对象拥有了一个proto属性,而这个属性就是指向Parent()构建函数的原型prototype属性,因此新创建的这个对象可以访问到say()方法。当child实现继承后,new 的proto属性是指向new Parent()这个对象的,因此它可以访问到new Parent()的name属性和proto属性,也就可以通过new Parent()的proto属性访问到say()方法。
原型链是通过从下往上找的,如果new child()自己有一个name属性,那么它会直接访问自己的那个name属性,但是如果自己没有name属性,它就会去找new Parent()的name属性。
如图:
这种模式的缺点是既继承了原型中的属性,也继承了父对象的‘自己的属性’,比如说如图的name属性。
类式继承2——借用构造函数
function Child(a, c, b, d) {
Parent.apply(this, arguments);
}
这个方式里,子对象是直接复制了父对象的成员,不过它访问不到prototype上的属性。
利用借用构造函数方法可以实现多继承:
function Cat() {
this.legs = 4;
this.say = function () {
return "meaowww";
}
}
function Bird() {
this.wings = 2;
this.fly = true;
}
function CatWings() {
Cat.apply(this);
Bird.apply(this);
}
var jane = new CatWings();
console.dir(jane);