说到继承,现实生活中就有子承父业,子承母业等等,意思就是孩子从父母手中继承到家业,但这份家业是从父母手中转接到孩子手中,一旦转接了,那就是属于孩子而不属于父母了。
而js中也有所谓的继承,但会区别于现实生活中的继承。
在js中,继承是值子类自动共享父类数据结构和方法的一种机制,是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
那么,关于继承的方法有以下几种
1、原型链继承
function Live(){
this.food = "土豆";
}
Live.prototype.showFood = function(){
alert(this.food);
}
function live(){
}
live.prototype = new Live();
var p1 = new live();
p1.showFood();//土豆
此种继承方式会将原型对象上的所以属性和方法在实例*享,继承较单一,并且不能向父类进行传参。
function Live(){
this.food =["土豆"];
}
function live(){
}
live.prototype = new Live();
var p1 = new live();
p1.food.push("番茄")
var p2 = new live();
alert(p1.food);//土豆,番茄
alert(p2.food);//土豆,番茄
而当属性为引用类型的情况下,则会出现一个实例的属性改变,其他实例也跟着一起变化的情况。
2、构造函数继承
function Live(food){
this.food = food;
}
Live.prototype.showFood = function(){
alert(this.food)
}
var p1 = new Live("土豆");
p1.showFood = function(){
alert("我爱吃" + this.food)
}
var p2 = new Live("土豆");
p1.showFood();//我爱吃土豆
p2.showFood();//土豆
通过构造函数继承到的子类实例可以向父类传参,并且能避开上一种方法出现的问题,但每次在构建一个新的子类实例对象的时候,需要重复调用到父类,即构造函数无法复用。
另外ECMA6还推出了class语法,同样可作为继承的一种方法
3、class继承
class Live{
constructor(food){
this.food = food;
}
showFood(){
alert(this.food)
}
}
var p1 = new Live("土豆");
p1.showFood = function(){
alert("我爱吃" + this.food)
}
var p2 = new Live("土豆");
p1.showFood();//我爱吃土豆
p2.showFood();//土豆
此方法跟上述的构造函数继承基本一致
4、寄生式继承
function Live(o){
var live = Object.create(o);
live.showFood = function(){
alert("土豆");
}
return live;
}
var cook ={
food: "番茄",
}
var p1 = Live(cook);
p1.showFood()//土豆
console.log(p1.food);//番茄
此种继承方法与原型继承类似,但是没用到原型,无法复用。
5、组合型继承
function Live(food){
this.food = food;
}
Live.prototype.showFood = function(){
alert("我喜欢吃" + this.food);
}
function live(food,time){
//继承属性,构造函数的伪装
Live.call(this, food);
this.time = time;
}
live.prototype = Object.create(Live.prototype)
//Worker.prototype = Object.create(Person.prototype);
// var p2 = new Live("土豆");
var p1 = new live("土豆",30);
p1.showFood()//我爱吃土豆
alert(p1.time)//30
此种继承方式是结合了原型以及构造函数的继承,避免了重复调用,间接的让live.prototype直接能访问得到Live.prototype。
总的来说一般用到组合型的继承会比较多,构造函数模式用于定义实例属性,原型模式用于定义共享的属性和方法。
即可以共享方法,又可以向构造函数传递参数,集两种模式之长!