JS 实现七种继承方法

本文详细介绍了JavaScript中常见的继承模式,包括原型链继承、构造函数继承、实例继承、拷贝继承、组合继承、寄生组合继承以及ES6的类继承。每种方式的特点、优缺点都进行了阐述,如原型链继承的属性共享问题,构造函数继承无法继承原型属性等。通过这些继承方式,可以更好地理解和应用JavaScript的面向对象编程。
摘要由CSDN通过智能技术生成
1.原型链继承

将父类的实例作为子类的原型(利用原型让一个引用类型继承另一个引用类型)

特点:

  • 实例是子类的实例也是父类的实例,父类新增的原型方法/属性,子类都能访问

缺点:

  • 来自原型对象的所有属性被所有实例共享,
  • 无法实现多继承
  • 无法给父类构造函数传参
function person(){}
people.prototype = new person()
people.prototype.name = 'lisa'
let obj = new people()
2.借用构造函数继承

复制符类的实例属性给子类(在子类构造函数中调用超类型构造函数)

特点:

  • 可以向父类传递参数
  • 可以实现多继承(apple或call多个父类)
  • 解决了原型中包含实例引用类型被所有实例共享的问题

缺点:

  • 方法都在构造函数中定义,无法复用
  • 不能继承原型属性和方法
function person(age){
	people.call(this)
	this.age = age || '20'
}
let obj = new person()
3.实例继承

借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型,为父类实例添加新属性,作为子类实例返回

特点:

  • 不限制调用方法,new people() / people()

缺点:

  • 实例是父类的实例,不是子类的实例
  • 不支持多继承
  • 包含应用类型的值会被所有实例共享
function person(name){
	let people = new person()
	people.name = name || 'lisa'
	return people()
}
4.拷贝继承

特点:

  • 支持多继承
    缺点:

  • 效率较低,内存占用高(因为要拷贝父类的属性)

  • 无法获取父类不可枚举(不能使用for in 访问到)的方法

function Cat(name){
	var animal = new Animal()
	for(for p in animal){
		Cat.prototype[p] = animal[p]
	}
	Cat.prototype.name = name || 'lisa'
}
var cat = new Cat()
console.log(cat.name)
console.log(cat instanceof Animal) //false
console.log(cat instanceof Cat)  //true
5.组合继承

调用父类构造函数,继承父类的属性,通过将父类实例作为子类原型

特点:

  • 实现函数复用
  • 可以继承原型的属性和方法

缺点:

  • 调用了两次父类,产生了两个实例
//父类
function People(name,age){
	this.name = name || 'lisa'
	this.age = age || '20'
}
//方法
Paople.prototype.eat = funciton() {
	return this.name + this.age +'eat food'   
}
//子类
function Woman(name,age){
	People.call(this,anem,age)     //继承父类的属性
}
Woman.prototype = new People()
Woman.prototype.constructor = Woman
let obj = new Woman('rose',21)
obj.eat()
6.寄生组合继承

通过寄生方式来修复组合继承的不足,砍掉父类的实例属性

特点:

  • 只调用一次超类构造函数,效率高,避免在超类型的prototype上创建不必要的属性
  • 与此同时,原型链保持不变
function People(name,age){
	this.name = name || 'lisa'
	this.age = age || '20'
}
//方法
Paople.prototype.eat = funciton() {
	return this.name + this.age +'eat food'   
}
//子类
function Woman(name,age){
	People.call(this,anem,age)     //继承父类的属性
}
(function(){   //创造父类方法
	let super = function(){}
	super.prototype = People.prototype
	Woman.prototypr = new super()
})()
Woman.prototypr.constructor = Woman
let obj = new Woman()

7.ES6 继承
Class People{
	constructor(name='liu',age='20'){
		this.name = name
		this.age = age
	}
	eat() {
		console.log(`${this.name} ${this.age}`)
	}
}
Class Woman extends People{    //继承父类
	constructor(name='li',age='21'){
		super(name,age)   //继承父类属性
	}
	eat() {
		super.eat()  //继承父类方法
	}
}

let obj = new Woman('luo')
obj.eat()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值