JS继承

JS继承方式

在这里插入图片描述

JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。

那么如何在JS中实现继承呢?JS实现继承有多重方式,但是没中方式都有优缺点。

常见的继承方法有:

  • 原型链继承

  • 构造继承

  • 实例继承

  • 拷贝继承

  • 组合继承

  • 寄生组合继承

  • ES6-Class-Extends

父类

首先我们先定义一个父类,实现代码如下:

function Animal( name="Animal" ){
    // 属性
    this.name = name;
    // 实例方法
    this.showName = ()=>{
    	console.log( `showName: ${this.name}` );
    }
}

// 原型方法
Animal.prototype.outputName = function(){
    console.log( `outputName: ${this.name}` );
}

继承方式

原型链继承

将父类的实例作为子类的原型

Cat.prototype = new Animal();

function Cat( name="maomi" ){
	this.name = name;
}
Cat.prototype = new Animal();


// 测试代码
let cat = new Cat();
cat.showName();							// showName: maomi
cat.outputName();						// outputName: maomi
console.log(cat instanceof Animal); 	//true 
console.log(cat instanceof Cat); 		//true

缺点:

  • 无法实现多继承

  • 创建子类实例时,无法向父类构造函数传参

构造继承

复制父类的实例属性给子类

Animal.call(this);

function Cat(name){
  Animal.call(this);
  this.name = name || 'maomi';
}

// 测试代码
var cat = new Cat();
cat.showName();							// showName: maomi
// cat.outputName();					// 报错。无法执行
console.log(cat instanceof Animal); 	// false
console.log(cat instanceof Cat); 		// true

缺点:

  • 只继承父类的实例属性/方法,无法继承原型的属性/方法

实例继承

在构造函数实例化父类,然后作为子类实例返回

function Cat( name="maomi" ){
	var instance = new Animal();
	instance.name = name;
	return instance;
}

// 测试代码
var cat = new Cat();
cat.showName();						// showName: maomi
cat.outputName();					// outputName: maomi
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); 	// false

缺点:

  • 实例是父类的实例,不是子类的实例

拷贝继承

通过对父类实例可枚举对线进行拷贝

function Cat( name="maomi" ){
	let animal = new Animal();
	for( let _prototype in animal ){
		Cat.prototype[_prototype] = animal[_prototype];
	}
	this.name = name;
}

// 测试代码
var cat = new Cat();
cat.showName();						// showName: maomi
cat.outputName();					// outputName: maomi
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); 	// false

缺点:

  • 实例是父类的实例,不是子类的实例

组合继承

构造继承+原型链阶层,修复原型链指向

function Cat( name="maomi" ){
	Animal.call( this );
	this.name = name;
}

Cat.prototype = new Animal();

// 测试代码
var cat = new Cat();
cat.showName();						// showName: maomi
cat.outputName();					// outputName: maomi
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); 	// true

缺点:

  • 调用了两次父类构造函数,生成了两份实例

寄生组合继承

通过构造继承复制父类属性

然后修复原型链

function Cat( name="maomi" ){
	Animal.call( this );
	this.name = name;
}

(function(){
  // 创建一个没有实例方法的类
  var Super = function(){};
  Super.prototype = Animal.prototype;
  //将实例作为子类的原型
  Cat.prototype = new Super();
})();

Cat.prototype.constructor = Cat; 

// 测试代码
var cat = new Cat();
cat.showName();						// showName: maomi
cat.outputName();					// outputName: maomi
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); 	// true

ES6继承

class Animal{
	constructor( name="Animal" ){
		this.name = name;
	}
	showName(){
		console.log( this.name )
	}
}

class Cat extends Animal{
	constructor( name="Maoni" ){
		super( name )
	}
}


let cat = new Cat();
cat.showName();			// Maoni

【参考文章】

JS实现继承的几种方式

js继承的几种方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值