一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
面试中js的继承是一个很高频的问题,记得我当时脱口而出继承有:原型链继承、构造函数继承、组合继承、原型继承、寄生式继承、寄生组合继承,一股脑全部说出来
我本以为面试官会微微点头,他波澜不惊的说到:那你在开发中是怎么用的,当时我就蒙,我们都知道js的就是过原型链的继承才实现了我们可以用数组、对象、函数的一些方法,但我们都是被动的使用,日常开发中我们有主动用过继承嘛?
答案是有的,记住这几个场景,起码面试被问到继承,你应该没问题了
1、原型链继承
原型链继承的原理很简单,并且日常开发中我们会主动使用到,咱们可以举例一下
function Prosen(age, name) {
this.name = name
this.age = age
}
Prosen.prototype.fn = () => {
console.log(111);
}
Prosen.prototype.genter = '男'
function Prosen1(age, name) {
this.name = name
this.age = age
}
// 这里是将Prosen1的原型等于Prosen的实例对象,Prosen1就可以访问Prosen原型上的方法
Prosen1.prototype = new Prosen()
let p1 = new Prosen1(23, '小王')
p1.fn()
console.log(p1.genter);
原型链继承是通过把想要继承的构造函数的实例对象直接放在继承者的原型上,因为实例对象可以访问构造函数原型上的方法,把实例对象放在继承者的原型上,继承者通过实例对象访问构造函数原型上的方法,并且继承者的实例对象也可以访问到构造函数的原型的方法
开发中当我们想访问另一个对象原型上的方法是可以使用原型链继承
2、ES6中的class继承
function Prosen(age, name) {
this.name = name
this.age = age
}
Prosen.prototype.fn = () => {
console.log(111);
}
// 使用class关键字继承时要用extends,如果子类没有自己的属性方法,可以不用写constructor,但是需要添加自己的属性和方法一定要用constructor,并且要先用super借用父构造函数,进行实例的属性初始化
class preson extends Prosen {
constructor(name, age) {
super(name, age)
this.name = name
}
}
const p1 = new preson(22, '周桑')
console.log(p1);
class继承一定要注意使用extends关键字,并且子类要添加自己的属性方法时,需要通过constructor和super这两个方法
面试官问我们开发中class继承在哪里用到,我们可以说个最简单的例子,react中的类组件就用的是class继承,所以类组件才能有状态和生命周期
import React from 'react'
class Com extends React.Component {
render() {
return <div>
类组件
</div>
}
}
export default Com
3、TypeScript中接口的继承
interface Point2D { x: number; y: number }
// 继承 Point2D
interface Point3D extends Point2D {
z: number
}
const obj3: IPoint3D = {
x: 1,
y: 2,
z: '小王',
}
再比如我上一篇帖子封装获取数据并渲染的hooks中就用到了继承
import { RootState } from '@/types/store'
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
// T extends keyof RootState继承RootState的键名,stateName:T约定传过来的参数也只能是RootState的键名
export default function useInitState<T extends keyof RootState> (action: ()=>void, stateName:T) {
const dispatch = useDispatch()
useEffect(() => {
dispatch(action())
}, [])
// state[stateName]====state里放的是个变量,直接写.等于是字符串
return useSelector((state:RootState) => state[stateName])// 这里return的是state.profile这个对象
}
这三个应用场景被问到继承的时候可以说出来,我觉得要比背出那个些个继承方法要好很多,当然时间充裕的话,那些继承方法也值得我们去写写例子