…
}
let student:Student = {
//这边即使接口Sudent里面什么都没写,那么也需要实现接口Person里面的规则
}
到了ES6的时代,有了关键字class,那么class能否直接实现接口呢,答案是可以的,使用关键字:implements
interface ClockInterface {
currentTime: Date;
}
class Clock implements ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
当然,也可以在接口中描述一个方法,在类里实现它,如同下面的setTime方法一样:
interface ClockInterface {
currentTime: Date;
setTime(d: Date);
}
class Clock implements ClockInterface {
currentTime: Date;
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) { }
}
============================================================
简单的说,一个良好的API,不仅要考虑支持当前的数据类型,也要能支持未来的数据类型,因此,通过泛型来创建可以重用的组件,也就是一个组件支持多种类型的数据,例如:
function person(arg: string): string {
return arg;
}
console.log(person(‘Oliver’))
定义了一个person,参数类型是字符串,也许当前我们是通过名字来命名的,所以使用string,但是将来也许就不是名字是ID来调用了,因此如果写死了string,那么重用性就会很差,未来将不能使用,因此就需要使用泛型,支持多种类型;
所以说到底,泛型也是一种类型,只是这种类型很抽象,需要到使用的时候才知道,而不是和string,number这种一开始就已经定义好了的类型一样
泛型的好处就是可以限定输入和返回是相同的类型,有人可能会说any,但是相比类型设置any,any做不到返回一定和输入的类型相同,比如:
function person(arg: any): any {
return arg;
}
输入的arg可以是数字类型,但是返回值的类型可以是字符串,那么输入的类型则和返回的类型不相同了,因此就可以使用泛型;
function person(arg:T):T{
return arg
}
我们给函数person设置了一个泛型,并且限定了参数arg的类型也是T,返回值的类型也是T,那么至少我们知道,输入和输出都是类型T,当然,此时的T没有具体的类型,接着就是我们使用了;
泛型的使用一种有两种方式:
第一种:
let output = identity(“myString”);
我们明确了,那么根据规则我们可以知道,输入必须是string类型,输出也肯定是string类型;
第二种:
let output = identity(“myString”);
这种我们可能更常用一点,原因很简单,少写了代码,但是功能是完全一摸一样的,TS的编译器会自动的去识别参数,因为通过设置泛型,我们确定了输入输出必须一致,那么此时输入的是字符串类型,那么输出必然的也必须是字符串类型;
当然,泛型也是可以在接口中使用的,先看一个示例:
function student(arg:T):T{
return arg
}
// 定义了一个接口GenericPerson
interface GenericPerson{
// 定义了一个函数
// :代表泛型
// (arg:T):参数也是泛型
// :T :返回值也是泛型T
(arg:T):T
}
// 定义了一个变量person,遵循的规则集是接口GenericPerson
let person:GenericPerson = function (arg) {
return arg
}
let person2:GenericPerson = student;
console.log(person(12333)) // 指定了泛型为number类型
console.log(person2(132333)) // 不指定类型,类型由ts自己判断
另外,通过 extends 可以为泛型增加约束,限定泛型的类型或者必须包含一定的属性,例子如下:
// 限定泛型,必须包含length属性,并且值必须是number类型或者是string类型
function student<T extends { length:number | string} >(arg:T):T{
return arg
}
let obj = {
length:10
}
console.log(student(obj))
// 限定了泛型必须是数字类型或者是字符串类型
function student<T extends number | string >(arg:T):T{
return arg
}
let obj = ‘10’
console.log(student(obj))
而在类中使用泛型,例子如下
// 在类名后面使用泛型
class CountNumber{
num1:T; // num1的类型是泛型T
num2:T = 1; // num2的类型是泛型T,默认值是1
constructor(num1:T,num2:T){
this.num1 = num1;
this.num2 = num2;
}
countNum():number{
// +号是ts提供的一种解决方案,不然会报错
return +this.num1 * +this.num2
}
}
// 可以限定泛型的类型,也可以不限定
const number = new CountNumber(10,20);
// 不限定
const number = new CountNumber(10,20);
console.log(number.countNum())
// 即使限定类型是字符串,但是通过“+”号,也可以转成数字,从而进行计算
const number2 = new CountNumber(‘10’,‘20’);
console.log(number2.countNum()) //200
当然,在类中的泛型也可以进行约束的,例如:
// 在类名后面使用泛型,传递过来的类型必须是数字类型
class CountNumber{
num1:T; // num1的类型是泛型T
num2:T = 1; // num2的类型是泛型T,默认值是1
constructor(num1:T,num2:T){
this.num1 = num1;
this.num2 = num2;
}
countNum():number{
// +号是ts提供的一种解决方案,不然会报错
return +this.num1 * +this.num2
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
总结一下这三次面试下来我的经验是:
-
一定不要死记硬背,要理解原理,否则面试官一深入就会露馅!
-
代码能力一定要注重,尤其是很多原理性的代码(之前两次让我写过Node中间件,Promise.all,双向绑定原理,被虐的怀疑人生)!
-
尽量从面试官的问题中表现自己知识的深度与广度,让面试官发现你的闪光点!
-
多刷面经!
我把所有遇到的面试题都做了一个整理,并且阅读了很多大牛的博客之后写了解析,免费分享给大家,算是一个感恩回馈吧,有需要的朋友【点击我】免费获取。祝大家早日拿到自己心怡的工作!
篇幅有限,仅展示部分内容
识的深度与广度,让面试官发现你的闪光点!
- 多刷面经!
我把所有遇到的面试题都做了一个整理,并且阅读了很多大牛的博客之后写了解析,免费分享给大家,算是一个感恩回馈吧,有需要的朋友【点击我】免费获取。祝大家早日拿到自己心怡的工作!
篇幅有限,仅展示部分内容