javascript中的继承方式

更新时间:2020-06-30 11:16:15 点击次数:966次
1.原型对象(prototype)继承
优点:简单,方便,易操作
缺点:
不能继承构造函数里的属性和方法
只能继承原型对象身上的属性和方法
function Parent(){
this.name = "admin";
this.sayHi = function(){
console.log("hi");
}
}
Parent.prototype.show = function(){
console.log("Parent的方法");
}

function Child(){}

//原型对象继承:深拷贝
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i];
}

var p = new Parent();
console.log(p.name);    //admin
p.sayHi();     //hi
p.show();     //Parent的方法

var c = new Child();
console.log(c.name);    //undefined
//c.sayHi();     //报错:c.sayHi is not a function
c.show();     //Parent的方法


Child.prototype.show = function(){
console.log("Child自己写的方法");
}
//不会覆盖Parent实例的方法
c.show();     //Child自己写的方法

2.原型链(__proto__)继承
优点:
更加的简单,方便,易操作
可以继承构造函数中的方法和属性
可以继承原型身上的方法和属性
缺点:不方便传参
function Parent(a){
this.name = "admin";
this.sayHi = function(){
console.log("hi");
};
this.age = a;
}
Parent.prototype.show = function(){
    console.log("Parent的方法");
console.log(this.age);
}

function Child(){}

var p = new Parent("18");
console.log(p.name);    //admin
p.sayHi();             //hi
p.show();             //Parent的方法  18

//原型链继承
Child.prototype = new Parent();
//Child实例c ---> __proto__ ---> Child.prototype ---> Parent的实例 ---> __proto__ ---> Parent.prototype

var c = new Child();
console.log(c.name);    //admin
c.sayHi();             //hi
c.show();             //Parent的方法   undefined

Child.prototype.show = function(){
console.log("Child自己写的方法");
}
//不会覆盖Parent实例的方法
c.show(); //Child自己写的方法

构造函数继承
优点:
方便传参
可以实现多继承
缺点:
只能继承构造函数内部的属性或方法,
不能继承原型身上的属性或方法
function Parent(s){
this.skill = s;
this.sayHi = function(){
console.log("hi");
};
}
Parent.prototype.show = function(){
console.log("parent的方法");
}

function Child(n){
//构造函数继承:改变this指向
Parent.call(this,n);
}

var p = new Parent("正式工");
console.log(p.skill); //正式工
p.sayHi(); //hi
p.show(); //parent的方法

var c = new Child("实习工");
console.log(c.skill); //实习工
c.sayHi(); //hi
//c.show(); //报错:c.show is not a function

混合继承(构造函数继承 + 原型对象继承)
优点
方便传参
可以实现多继承构造函数
可以继承构造函数中的方法和属性
可以继承原型身上的方法和属性
缺点:
略复杂
原型链继承时,传参时有隐患
function Parent(s){
this.skill = s;
this.sayHi = function(){
console.log("hi");
};
//测试原型链继承时,参数隐患,报错:Cannot read property 'split' of undefined
//测试原型对象继承时,不报错。
this.skill.split();
}
Parent.prototype.show = function(){
console.log("parent的方法");
}

function Child(s){
//构造函数继承
Parent.call(this,s);
}

//原型对象继承:没有传参隐患
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i];
}

//原型链继承:有传参隐患
//Child.prototype = new Parent();

var p = new Parent("正式工");
console.log(p.skill); //正式工
p.sayHi(); //hi
p.show(); //parent的方法

var c = new Child("实习工");
console.log(c.skill); //实习工
c.sayHi(); //hi
c.show(); //parent的方法

Child.prototype.show = function(){
console.log("Child自己写的方法");
}
//不会覆盖Parent实例的方法
c.show(); //Child自己写的方法

ES6的class继承(构造函数继承 + 原型链继承)
优点:
方便传参
可以继承构造函数中的方法和属性
可以继承原型身上的方法和属性
关键字:
extends
super
class Parent{
constructor(s){
this.skill = s;
this.name = "admin";
}
show(){
console.log("parent的方法");
}
}

class Child extends Parent{
constructor(s){
super(s);   //改变this指向和传参的作用
this.skill = s;
this.name = "anran";
}
show(){
console.log("Child自己写的方法");
}
}

var p = new Parent("正式工");
console.log(p.skill);       //正式工
console.log(p.name);        //admin
p.show();         //parent的方法

var c = new Child("实习工");
console.log(c.skill);       //实习工hello
//不会覆盖Parent实例的属性和方法
console.log(c.name);        //anran
c.show();         //Child自己写的方法

总结比较
~ 原型对象继承 原型链继承 构造函数继承 混合继承(构造函数继承+原型对象继承) ES6class继承(构造函数继承+原型链继承)
优点 简单方便易操作 1.更加简单方便易操作,2.可以继承构造函数中的方法和属性,3.可以继承原型身上的方法和属性 1.方便传参,2.可以实现多继承 1.方便传参,2.可以实现多继承,3.可以继承构造函数中的方法和属性,4.可以继承原型身上的方法和属性 1.方便传参,2.可以实现多继承,3.可以继承构造函数中的方法和属性,4.可以继承原型身上的方法和属性
缺点 1.不能继承构造函数中的方法和属性,2.只能继承原型身上的方法和属性 不方便传参 1.只能继承构造函数中的方法和属性,2.不能继承原型身上的方法和属性 1.略复杂,2.原型链继承时依然有参数隐患

本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是一个个人学习交流的平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽,造成漏登,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

回到顶部
嘿,我来帮您!