【前端面试】JS中通过原型链和class语法分别实现类的继承

【前端面试】JS中通过原型链和class语法分别实现类的继承


JS中的 本质上是一个 function类型的对象,这是JS的独特之处。

原型链实现继承

在ES6的class语法推出之前,要实现类的继承要通过修改原型链来实现:

  • 首先定义一个父类,本质上是定义父类的构造函数,其对应的Person.prototype会自动被创建
function Person(name, age) {
	this.name = name
	this.age = age
}
Person.prototype.setName = function(name) {
	this.name = name
}
  • 然后定义一个子类,通过在子类中用call函数,以子类的身份调用父类的构造函数,实现继承父类的成员变量
function Student (name, age) {
	Person.call(this,name,age)
}

这样做还不够,因为父类的成员函数还没有被继承。可以通过将Studentprototype的原型链__proto__指向Personprototype,来实现这一功能。

Student.prototype = new Person //这里无需入参,参数默认是undefined就行,
// 反正成员变量已经在前一步通过call继承到子类型Student对象上了
// 如果需要调用Student的成员变量,也轮不到沿着原型链找到这个new Person头上

然后试一下功能

const s1 = new Student('Bob', 23)
s1.setName('Tom')
console.log(s1)

在这里插入图片描述
看起来大功告成!
但是…还有一个细节没有处理,那就是:Student.prototype.constructor此刻还指向Person,而正确的情况是:它应该指向Student本身,因此应该:

Student.prototype.constructor = Student

一个细节

Student.prototype = new Person这一步中,我提到了可以不带参数,因为Student对象本身就有nameage属性,只不过是undefined,因此不会沿着原型链找到new Person上。这里做个简单的测试。

Student.prototype = new Person('Jerry', 100) //改变Student原型链的时候带入参
const student1 = new Student  //新建student实例的时候不带入参
console.log(student1.name)  //undefined 而不是 Jerry

ES6 class 语法实现继承

要实现和上面的代码一样的逻辑,我们应该这么做:

  • 先定义父类Person
class Person {
	constructor(name, age) {
		this.name = name
		this.age = age
	}
	setName(newName) {
		this.name = newName
	}
}

然后定义子类Student,继承父类Person

class Student extends Person{
	constructor(name, age){
		super(name, age)
	}
}

测试一下:

const student1 = new Student('Tom', 24)
student1.setName('Jerry')

结果如下:
在这里插入图片描述
检查继承关系:
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值