一、原型链继
1.基本思想
利用原型链来实现继承,超类的一个实例作为子类的原型
2、具体实现
1 function F() {} 2 3 //原型属性,原型方法: 4 5 F.prototype.name="Lee"; 6 7 F.prototype.age=33; 8 9 F.prototype.run=function(){ 10 11 return this.name+" "+this.age+" running"; 12 13 } 14 15 var f = new F(); 16 17 console.log(f.name); 18 19 console.log(f.run);
3.优缺点
1)优点
简单明了,容易实现
实例是子类的实例,实际上也是父类的一个实例
父类新增原型方法/原型属性,子类都能访问到
2)缺点
所有子类的实例的原型都共享同一个超类实例的属性和方法
无法实现多继承
在创建子类的实例时 不能向父类的构造函数传递参数
二、构造函数继承
1。基本思想
通过使用call、apply方法可以在新创建的对象上执行构造函数,用父类的构造函数来增加子类的实例
2、具体实现
1 function F() { 2 3 // 属性 4 5 this.name = name || 'dragon'; 6 7 // 实例方法 8 9 this.sleep = function(){ 10 11 console.log(this.name + '正在睡觉!'); 12 13 } 14 15 16 17 } 18 19 function C(name){ 20 21 F.call(this); 22 23 this.name = name || 'Tom'; 24 25 } 26 27 var c=new C() 28 29 console.log(c.name); 30 31 console.log(c.sleep());
3.优缺点
1)优点
简单明了,直接继承超类构造函数的属性和方法
2)缺点
无法继承原型链上的属性和方法
三、实例继承
1.基本思想
为父类实例添加新特性,作为子类实例返回
具体实现
1 function F() { 2 3 // 属性 4 5 this.name = name || 'Animal'; 6 7 // 实例方法 8 9 this.sleep = function(){ 10 11 console.log(this.name + '睡觉'); 12 13 } 14 15 } 16 17 function C(name){ 18 19 var instance = new F(); 20 21 instance.name = name || 'Tom'; 22 23 return instance; 24 25 } 26 27 var c = new C(); 28 29 console.log(c.name); 30 31 console.log(c.sleep());
特点:
1. 不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
缺点:
1. 实例是父类的实例,不是子类的实例
2. 不支持多继承
四、组合继承
1.基本思想
利用构造继承和原型链组合
2.具体实现
1 function F() { 2 3 // 属性 4 5 this.name = name || 'Animal'; 6 7 // 实例方法 8 9 this.sleep = function(){ 10 11 console.log(this.name + '正在睡觉!'); 12 13 } 14 15 } 16 17 function C(name){ 18 19 F.call(this);//构造函数继承 20 21 this.name = name || 'Tom'; 22 23 } 24 25 C.prototype = new F();//原型继承 26 27 var q=new C(); 28 29 console.log(q.name); 30 31 console.log(q.sleep());
3.优缺点
1)优点
解决了构造继承和原型链继承的两个问题
2)缺点
实际上子类上会拥有超类的两份属性,只是子类的属性覆盖了超类的属性
五、原型式继承
1.基本思想
采用原型式继承并不需要定义一个类,传入参数obj,生成一个继承obj对象的对象
2、具体实现
1 var obj = { 2 3 name: "qw", 4 5 age: "12", 6 7 ada:"asd" 8 9 } 10 11 12 13 function F(o) { 14 15 function C() {} 16 17 C.prototype = o; 18 19 return new C(); 20 21 } 22 23 var q= F(obj) 24 25 console.log(q.name); 26 27 console.log(q.age);
3.优缺点
1)优点:
直接通过对象生成一个继承该对象的对象
2)缺点:
不是类式继承,而是原型式基础,缺少了类的概念
六、寄生式继承
原型式+工厂模式
解决了组合继承两次调用构造函数的问题
1.基本思想
创建一个仅仅用于封装继承过程的函数,然后在内部以某种方式增强对象,最后返回对象
2、具体实现
1 //临时中转函数 2 3 function obj(o) { 4 5 function F() {} 6 7 F.prototype = o; 8 9 return new F(); 10 11 } 12 13 //寄生函数 14 15 function create(o){ 16 17 var q= obj(o); 18 19 //可以对f进行扩展 20 21 q.sleep = function(){ 22 23 return this.name+”睡觉”; 24 25 } 26 27 return q; 28 29 } 30 31 var box = { 32 33 name: 'Lee', 34 35 age: 100, 36 37 family: ['Dad', 'Mom', 'Sister'] 38 39 }; 40 41 var box1 = create(box); 42 43 alert(box1.name); 44 45 alert(box1.run());
3.优缺点
1)优点:
* 原型式继承的一种拓展
2)缺点:
* 依旧没有类的概念
七、寄生组合继承
通过调用构造函数来继承属性,通过原型链混成形式继承方法,与组合继承不同之处在于子类型只继承了超类型原型的一个副本,并未继承其构造函数。因此只需要调用一次超类型构造函数。
1.基本思想
结合寄生式继承和组合式继承,完美实现不带两份超类属性的继承方式
2.具体实现
1 //临时中转函数 2 3 function obj(o) { 4 5 function F() {} 6 7 F.prototype = o; 8 9 return new F(); 10 11 } 12 13 //寄生函数 14 15 function create(box,desk){ 16 17 var q = obj(box.prototype); 18 19 q.construtor=d; 20 21 d.prototype=q; 22 23 } 24 25 function B(name,age){ 26 27 this.name=name; 28 29 this.age=age; 30 31 } 32 33 B.prototype.run=function(){ 34 35 return this.name + " " + this.age + " running..." 36 37 } 38 39 function D(name,age){ 40 41 Box.call(this,name,age); 42 43 }
//通过寄生组合继承来实现
1 create(B,D);//替代D.prototype=new B(); 2 3 var d= new D('Lee',100); 4 5 alert(d.run());
3.优缺点
1)优点:
完美实现继承,解决了组合式继承带两份属性的问题
2)缺点:
过于繁琐,故不如组合继承
Es6. 继承
1 lass father{ 2 3 constructor(name){ 4 5 this.name=name 6 7 this.names=[1,2,3] 8 9 } 10 11 getname(){ 12 13 console.log(this.name); 14 15 } 16 17 } 18 19 class child extends father{ 20 21 constructor(name){ 22 23 super(name); 24 25 } 26 27 sayHello(){ 28 29 console.log("sayHello"); 30 31 } 32 33 static hh(){ 34 35 console.log("hh") 36 37 } 38 39 } 40 41 var cc=new child("juanjuan"); 42 43 cc.sayHello(); 44 45 cc.getname(); //juanjuan 46 47 child.hh(); //hh 48 49 cc.names.push("wqwq"); 50 51 var c1=new child("sasasa"); 52 53 console.log(c1.names) //[1,2,3]