一、原型链继
1.基本思想
利用原型链来实现继承,超类的一个实例作为子类的原型
2、具体实现
function F() {}
//原型属性,原型方法:
F.prototype.name="dragon";
F.prototype.age=30;
F.prototype.run=function(){
return this.name+" "+this.age+" running";
}
var f = new F();
console.log(f.name);//dragon
console.log(f.run());//dragon 30 running
3.优缺点
1)优点
简单明了,容易实现
实例是子类的实例,实际上也是父类的一个实例
父类新增原型方法/原型属性,子类都能访问到
2)缺点
所有子类的实例的原型都共享同一个超类实例的属性和方法
无法实现多继承
在创建子类的实例时 不能向父类的构造函数传递参数
二、构造函数继承
1。基本思想
通过使用call、apply方法可以在新创建的对象上执行构造函数,用父类的构造函数来增加子类的实例
2、具体实现
function F() {
// 属性
this.name = 'dragon';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
function C(name){
F.call(this);//1
this.name = name || 'Tom';
//F.call(this); //2
}
var c=new C()
console.log(c.name);//1 Tom 2 dragon
console.log(c.sleep());//1 Tom正在睡觉! 2 dragon正在睡觉!
3.优缺点
1)优点
简单明了,直接继承超类构造函数的属性和方法
2)缺点
无法继承原型链上的属性和方法
三、实例继承
1.基本思想
为父类实例添加新特性,作为子类实例返回
具体实现
function F() {
// 属性
this.name = 'dragon';
// 实例方法
this.sleep = function () {
console.log(this.name + '睡觉');
}
}
function C(name) {
var instance = new F();
instance.name = name || 'Tom';
return instance;
}
var c = new C();
console.log(c.name);//Tom
console.log(c.sleep());//Tom睡觉
特点:
1. 不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
缺点:
1. 实例是父类的实例,不是子类的实例
2. 不支持多继承
四、组合继承
1.基本思想
利用构造继承和原型链组合
2.具体实现
function F() {
// 属性
this.name = 'dragon';
// 实例方法
this.sleep = function () {
console.log(this.name + '正在睡觉!');
}
}
function C(name) {
F.call(this);//构造函数继承
this.name = name || 'Tom';
}
C.prototype = new F();//原型继承
var q = new C();
console.log(q.name);//Tom
console.log(q.sleep());//Tom正在睡觉!
3.优缺点
1)优点
解决了构造继承和原型链继承的两个问题
2)缺点
实际上子类上会拥有超类的两份属性,只是子类的属性覆盖了超类的属性
五、原型式继承
1.基本思想
采用原型式继承并不需要定义一个类,传入参数obj,生成一个继承obj对象的对象
2、具体实现
var obj = {
name: "qw",
age: "12",
ada: "asd"
}
function F(o) {
function C() {}
C.prototype = o;
return new C();
}
var q = F(obj)
console.log(q.name);//qw
console.log(q.age);//12
3.优缺点
1)优点:
直接通过对象生成一个继承该对象的对象
2)缺点:
不是类式继承,而是原型式基础,缺少了类的概念
六、寄生式继承
原型式+工厂模式
解决了组合继承两次调用构造函数的问题
1.基本思想
创建一个仅仅用于封装继承过程的函数,然后在内部以某种方式增强对象,最后返回对象
2、具体实现
//临时中转函数
function obj(o) {
function F() {}
F.prototype = o;
return new F();
}
//寄生函数
function create(o) {
var q = obj(o);
//可以对F进行扩展
q.sleep = function () {
return this.name + "睡觉";
}
return q;
}
var box = {
name: 'dragon', age: 100,
family: ['Dad', 'Mom', 'Sister']
};
var box1 = create(box);
console.log(box1.name);//dragon
console.log(box1.run());//dragon睡觉
3.优缺点
1)优点:
* 原型式继承的一种拓展
2)缺点:
* 依旧没有类的概念
七、寄生组合继承
通过调用构造函数来继承属性,通过原型链混成形式继承方法,与组合继承不同之处在于子类型只继承了超类型原型的一个副本,并未继承其构造函数。因此只需要调用一次超类型构造函数。
1.基本思想
结合寄生式继承和组合式继承,完美实现不带两份超类属性的继承方式
2.具体实现
//临时中转函数
function obj(o) {
function F() {
}
F.prototype = o;
return new F();
}
//寄生函数
function create(subType, superType){
// var protoType = Object.create(superType.prototype); //创建对象
var protoType = obj(superType.prototype); //创建对象
protoType.constructor = subType; //增强对象
subType.prototype = protoType; //指定对象
}
function Sup(name, age) {
this.name = name;
this.age = age;
}
Sup.prototype.run = function () {
return this.name + " " + this.age + " running..."
}
function Sub(name, age) {
Sup.call(this, name);
this.age = age;
}
create(Sub,Sup);//替代D.prototype=new B();
Sub.prototype.sayAge = function(){
return this.name + " " + this.age + " Sub..."
}
var d= new Sub('dragon',100);
console.log(d.run());//dragon 100 running...
console.log(d.sayAge());//dragon 100 Sub...
3.优缺点
1)优点:
完美实现继承,解决了组合式继承带两份属性的问题
2)缺点:
过于繁琐,故不如组合继承
Es6继承
class father{
constructor(name){
this.name=name
this.names=[1,2,3]
}
getname(){
console.log(this.name);
}
}
class child extends father{
constructor(name){
super(name);
}
sayHello(){
console.log("Hello");
}
static hh(){
console.log("hh")
}
}
var cc=new child("dragon");
cc.sayHello();//Hello
cc.getname(); //dragon
child.hh(); //hh
cc.names.push("wqwq");
var c1=new child("sasasa");
console.log(c1.names) //[1,2,3]
大神请指正 。。。。。。