javascript常见的四种继承方式

555 阅读3分钟

继承

知识点:
常见的四种继承方式,
各个继承的优缺点
继承面试考点。
js中的继承,主要是依靠原型链来实现的,原型链是继承的主要工具和方法。

继承的四种方式

原型继承
组合 继承
寄生组合继承
es6的extend继承

1、原型继承

原型继承额核心是把父类的实例作为子类的原型
特点:
父类的实例可以作为子类的实例
父类原有和新增的方法和属性,子类都能访问到
简单容易实现

缺点:
创建的子类实例不能传参
子类实例共享了父类构造函数的引用属性

var person = { 
	friends : ["Van","Louis","Nick"];
	 };
var p1 = Object.create(person); 
p1.friends.push("Rob");
var p2 = Object.create(person); 
p2.friends.push("Style"); 
console.log(person.friends); //"Van,Louis,Nick,Rob,Style"

2、组合继承

通过调用父类构造函数,继承父类的属性并保存传参的优点;然后通过将父类实例作为子类原型,实现函数复用。
特点:

  1. 可以继承实例属性和方法,也可以继承原型的属性和方法
  2. 函数的实例即是子类的实例,也是父类的实例
  3. 不存在引用属性共享问题。即子类的改变不会影响父类引用类型的共享
  4. 子类的实例可以传递参数
    5.所有子类可以复用父类的方法
//父类
function Father(name){
	this.name = name;
	this.colors = ['red','blue','green'];
}
//方法定义在原型对象上(共享)
Father.prototype.sayName = function (){
	alert(this.name);
};
function Son (name,age){
	Father.call(this,name);//核心:继承实例属性,第一次调用father()
	this.age = age;
}
//子类和父类共享的方法(实现了父类属性和方法的复用)
son.prototype = new Father ();//核心:继承实例属性,第二次调用Father()
son.prototype.constructor = son;//修复子类的constructor的指向

//优点一:可传参
var instance1 = new Son ('liuis',5);
var instance2 =  new son ('zhai',10);

//优点二:共享父类方法
instance1.sayName();//liuis
Instance.sayName();//zhai

//优点三:不共享父类引用属性
instance1.colors.push('black);
console.log(instance1.colors);//"red,blue,green,black" 
console.log(instance2.colors);//"red,blue,green"
}

3、寄生组合继承

寄生组合是结合了组合继承和原型继承两者的优点,而且没有缺点
通过寄生的方式,砍掉父类的实例属性,在再次调用父类的构造函数的时候,不会初始化两次实例方法和属性。避免组合继承的除了实现起来比较复杂之外都挺好的。

// 父类 function Father(name){ 
	this.name = name;
	this.colors = ["red","blue","green"]; 
}
// 方法定义在原型对象上(共享) 
Father.prototype.sayName = function(){ 
	alert(this.name); 
	};
function Son(name,age){ 
	Father.call(this,name); // 核心 
	this.age = age; 
 }
Son.prototype = Object.create(Father.prototype); // 核心: 
Son.prototype.constructor = Son; // 修复子类的 constructor 的指向

4、es6的extend继承

es6的extend继承其实就是寄生组合继承的语法糖
使用extends关键字扩展一个类并继承他的行为。
核心思想:
extends:内部相当于设置了Son.prototype = object.create(Father.prototype);
super():内部相当于调用了Father.call(this);

特点:
子类只要继承父类,可以不写constructor ,一旦写了 ,则在constructor中的第一句话必须是super
把父类当做普通方法的时候,给方法传递参数,让方法中的this是子类的实例

class Son extends Father { // Son.prototype.__proto__ = Father.prototype 
	constructor(y) { 
		super(200); // super(200) => Father.call(this,200) 
		this.y = y 
	} 
}

extends继承详解
这篇文章讲的就很详细。大家可以看一下