js继承的 6种方式

26 阅读2分钟

1.原型链继承 缺点:在包含引用类型数据时,会被所有实例共享,容易造成修改的混乱,以及在创建子类型时不能向超类型传递参数 2.构造函数 通过在子类型的(构造)函数中调用超类型的构造函数来实现,解决了不能向超类型构造函数传递参数的缺点 缺点:无法实现函数的复用,并且超类型原型定义的方法子类型也没有办法访问到

	function SuperType(){
		this.color = ['red', 'blue', 'green']
	}
	function SubType(){
		//继承了SuperType
		SuperType.call(this);
	}
	let instance1 = new SubType();
	instance1.color.push('purple');
	
	

3.组合继承 是将原型链和借用构造函数组合的一种方式,通过使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承 缺点:因为是以超类型的实例来作为子类型的原型,所以调用了两次超类的构造函数,造成了子类型的原型中多了很多不必要的属性

	function SuperType(name){
		this.name = name
		this.color = ['red', 'blue', 'green']
	}
	SuperType.prototype.sayName = function(){
		console.log(this.name);
	}
	function SubType(name, age){
		//继承属性
		SuperType.call(this, name);
		this.age = age
	}
	//继承方法
	SubType.prototype = new SuperType();
	SubType.prototype.construct = SubType;
	SubType.prototype.sayAge = function(){
		console.log(this.age)
	}
	let instance1 = new SubType('names', 99)
	instance1.color.push('black');
	
	

4.原型式继承 基于已有的对象来创建新的对象,实现原理是向函数中传入一个对象,然后返回一个以这个对象为原型的对象 该思路不是为了实现创造一种新类型,只是对某个对象实现一种简单继承,ES5中的 object.create()就是原型式继承 缺点和原型链方式相同 (一个传参, 一个属性共享)

	function object(o){
		function F(){};
		F.prototype = o;
		return new F();
	}
	
	

5.寄生式继承 思路为创建一个用于封装继承过程的函数,通过传入一个对象,然后复制一个对象的副本,并对其进行扩展,最后返回该对象,扩展过程可理解是继承 优点是对一个简单对象实现继承,如果这个对象不是我们的自定义类型; 缺点是在为对象添加函数时,无法实现函数的复用

	function createAnother(original){
		let clone = object(original);	//调用函数创建一个对象
		clone.sayHi = function(){		//某种方式增强这个对象
			console.log('Hello')
		}
		return clone;
	}
	let person = {name: 'names'};
	let anotherPerson = createAnother(person);
	anotherPerson.sayHi();
	
	

6.寄生式组合继承 组合继承的缺点就是使用超类型的实例作为子类型的原型,导致添加了不必要的原型属性,寄生式组合继承的方式是使用超类型的原型的副本 作为子类型的原型,这样就避免了创建不必要的属性

	function inheritPrototype(subType, superType){
		let prototype = object(superType.prototype);  // 创建原型对象是超类原型对象的一个实例对象
		prototype.constructor = subType;	// 弥补因为重写原型而失去的默认的 constructor 属性
		subType.prototype = prototype;		// 实现原型继承
	}