2022年5月21日 TypeScript
今天是第一记录学习进度,之前学习的效果并不好,收获只是了解了一些概念代码能力并没有进步,希望之后能有所改变。
今天计划初步学习一下,TS
TS在VScode中的自动编译
在tsconfig中设置js代码编译目录"outdor"配置
终端->运行任务->tsc:监视
类型注解
一种轻量级的为函数或者变量添加的约束
使用webpack打包TS
配置出现版本问题,,,不想换低版本node开摆
被舍友蛊惑去看动画片了...睡觉前上传一次
2022年5月22日
基本类型
srting
number
boolean 不知道该记些什么
ts中变量一开始是什么类型,后期赋值时只能用这个类型的数据
undedined和null
都可以作为其他类型的子类型,如赋值给number类型的变量
let num2: number = undefined
console.log(num2)
数组和元组
数组定义方式1:
let 变量名:数据类型[]=[值s]
let arr1:number[] = [10,20,30,40,50]
数组定义方式2:泛型
let 变量名: Array<数据类型> = [值s]
let arr2:Array<number> = [100,200,300]
注意:数组定义后,里面的数据类型必须和定义数组时的类型时一致的
元组:在定义元组时,就限定了类型和数据的个数
let arr3:[string,number,boolean] = ['学习',999.999,true]
注意:元组类型在使用的时候,数据类型的位置和数据的个数与定义时保持一致如:
console.log(arr3[0].split('')) //split分割数组的方法
console.log(arr3[1].toFixed(2)) //toFixed保留两位小数
枚举
enum类型是对JavaScript标准数据类型的一个补充
enum Color{
red,
green,
blue
}
// 定义一个Color的枚举类型的变量来接收枚举的值
let color:Color = Color.red
console.log
console.log(Color.red,Color.green,Color.blue)
any
为在编程阶段还不清楚的类型的变量指定类型,可能来自动态的内容,比如用户输入或第三方代码库
let str:any = 100
str='有点不想学了...'
console.log(str)
// 当一个数组中要存储多个数据,个数不确定,类型不确定,此时也可以使用any来定义数组
let arr: any[] = [100,'我不想学习了',true]
void
表示没有任何类型,当一个函数没有返回值时,通常其返回值类型是:void
// 在函数声明的时候,小括号后面使用;void,代表的是该函数没有任何返回值
function showMsg():void{
console.log('我爱学习')
}
console.log(showMsg())
object
object表示非原始类型
// object类型
// 定义一个函数,参数是object类型,返回值也是object类型
function getObj(obj:object):object{
console.log(obj)
return{
name:'卡卡西',
age:27
}
}
console.log(getObj({name:'佐助',age:'18'})
联合类型
表示取值可以为多种类型中的一种
// 定义一个函数得到一个数字或字符串值得字符串形式值
function getString(str:number|string):string{
return str.toString()
console.log(getString('123'))
}
// 定义一个函数得到一个数字或字符串值的长度
function getString(str:number|string):number{
return str.toString().length
}
console.log(getString('012345678'))
类型断言
编译器相信我,我知道自己在写什么
<类型>变量名
或 值 as 类型
类型推断
没有指定类型定义的时候会根据变量值推断一个类型
接口
接口时对象的状态(属性)和行为(方法)的抽象(描述),是一种类型,是一种规则,是一个能力一种约束
(()=>{
// 定义一个接口,该接口作为Person对象的类型使用,可以限定或者是约束该对象中的属性数据
interface IPerson{
readonly id:number // id是只读的
name:string
age:number
sex?:string // ? 问号代表是可有可无的 ,没有不会报错
}
// 定义一个对象,该对象的类型就是定义的接口IPerson
const person:IPerson={
id:1,
name:'学习哥',
age:18,
sex:'男'
}
})()
函数类型
为了使用接口表示函数类型,需要给接口定义一个调用签名就是一个小括号,里面写函数的参数
通过接口的方式,作为函数的类型使用
// 定义一个接口,用来作为某个函数的类型使用
interface ISearchFunc{
// 定义一个调用签名
(source:string,subString:string):boolean
}
// 定义一个函数,该类型就是上面定义的接口
const searchString:ISearchFunc = function (source:string,subString:string):boolean{
// 在source字符串中查找subString这个字符串
return source.search{subString} > -1
}
// 调用函数
console.log(searchString('学习','学'))
类类型
让类实现接口,可以把接口看作是类的类型
// 定义一个接口
interface IFly{
// 该方法没有实现
fly()
}
// 定义一个接口,这个类的类型就是上面定义的接口(IFly接口约束了当前这个Person类)
class Person implements IFly{
// 实现接口中的方法
fly()
console.log('大概这样下去可以')
}
// 实例化对象
const person = new Person()
persong.fly()
// 一个类可以被多个接口约束
class Person2 implements IFly,ISwim{
fly(){
console.log('学习')
}
swim(){
console.log('还是'){
}
}
// 实例化对象
const person2 = new Person2()
person2.fly()
person2.swim()
类可以通过接口的方式,来定义当前类的类型,类可以实现多个接口,接口中的内容需要正真实现
接口可以继承其他多个接口
interface IMyFlyAndSwim extends IFly, ISwim { }
// 定义一个类,直接实现IMyflyAndSwim这个接口
class Person3 implements IMyFlyAndSwim{
fly(){
console.log('学习')
}
swim(){
console.log('还是'){
}
}
const Person3 = new Person3()
person3.fly()
person3.swim()
接口和接口之间叫继承 类和接口之间叫实现
类
可以理解为模板,通过模板可以实例化对象
// ts中类的定义及使用
class Person{
// 定义属性
name:string
// 定义构造函数:为了将来实例化对象的时候,可以直接对属性的值进行初始化
constructor(name:string){
// 更新对象中的属性数据
this.name = name
}
// 定义实例方法
sayHi(){
console.log(`${this.name}爱学习`)
}
}
// ts中使用类,实例化对象,可以直接进行初始化操作
const person = new Person('我')
继承
类与类之间的关系
A类继承B类,A类叫子类,B类叫基类 也叫派生类和超类
// 定义一个类,作为基类
class Person{
// 定义属性
name:string
age:number
// 定义构造函数
constructor(name:string,age:number)
this.neam= name
this.age = age
}
// 定义实例方法
sayHi(str:string){
console.log(`我是:$(this.name},${str}`}
}
}
// 定义一个类,继承自Person
class Student extends Person{
constructor(ame:string,age:number){
// 调用父类中的构造函数,使用的是super
super(name,age)
}
// 可以调用父类中的sayHi方法
sayHi(){
super.sayHi('哈哈')
}
}
// 实例化Person
const person = new Person('学习','18')
person.sayHi('学习')
// 实例化Student
const stu = newStudent('大学习',81)
stu.sayHi()
子类中可以用super调用父类中的构造函数和实例方法
子类中可以重写父类方法
2022年 5月23日
多态
父类型的引用指向子类型的对象,不同类型的对象针对相同的方法,产生了不同的行为
// 定义一个父类
class Animal{
// 定义一个属性
name:string
// 定义一个构造函数
constructor(name:string){
// 更新属性
this.name = name
}
// 实例方法
run(distance:number){
console.log(`跑了$(distance)米`)
}
}
// 定义一个子类
class Dog extends Animal{
// 构造函数
constructor(name){
// 调用父类的构造函数,实现子类中属性的初始化操作
super(name)
}
// 实例方法,重写父类中的实例方法
run(distance:number = 5){
console.log(`跑了$(distance)米`)
}
}
// 再定义一个子类
class Pig extends Animal{
// 构造函数
constructor(name){
// 调用父类的构造函数,实现子类中属性的初始化操作
super(name)
}
// 实例方法,重写父类中的实例方法
run(distance:number = 10){
console.log(`跑了$(distance)米`)
}
}
// 实例化父类对象1
const ani : Animal = new Animal('动物')
ani.run()
// 实例化子类对象
const dog:Dog = new Dog('大黄')
dog.run()
// 实例化对象
const pig:Pif = new Pig('八戒')
pig.run()
========================================================
// 父类和子类的关系:父子关系,此时,父类类型创建子类对象
const dog1:Animal = new Dog('小黄')
dog1.run()
const pig1:Animal = new Pig('佩奇')
pig1.run()
// 该函数需要的参数是Animal类型的
function showRun(ain:Animal){
ani.run()
}
showRun(dog1)
showRun(pig1)
类中的成员修饰符
修饰符(类中的成员修饰符):主要是描述类中的成员(属性,构造函数,方法)的可访问性
// 类中的成员都有自己默认的访问修饰符,public
// private修饰符,类中的成员如果使用private来修饰,呢么外部无法访问这个成员数据包括子类
// protucted 外部无法访问,但是子类可以访问
我们可以在下面改
class Person{
// 属性
private name:string // 私有的类外部不能访问
// 构造函数
constructor(name:string){
this.name = name
}
// 方法
eat(){
console.log('我真的真的爱学习',this.name)
}
}
// 实例化对象
const per = new Person('哈哈')
// 在类的外部可以访问类的属性成员
console.log(per.name)
per.eat()
readonly修饰符
首先是一个关键字,可以对类中的属性成员进行修饰,该成员就不能在外部被随意修改了
readonly写在成员前面
构造函数中,可以对只读的属性成员的数据进行修改
构造函数中的参数可以使用readonly,public,privte,protected修饰,会出现对应的属性成员
// 定义一个类型
class Person{
// 属性
readonly name:string
constructor(name:string){
this.name = name
}
sayHi(){
console.log('我爱学习',this.name)
}
}
// 实例化对象
const person : Person = new Person('学习')
person.name = '加油学习' // 上面加了readonly这里就会报错
console.log(person)
console.log(person.name)
存取器
TS支持通过getters/setters来截取对象成员的访问,可有效控制对象成员的访问
// 外部可以传入姓氏和名字数据,同时使用set和get控制姓名的数据,外部也可以修改操作
class Person{
firstName:string
lastName:string
csonstructor(firstName:string,lastName:string)
this.firstName = firstName
this.lastName = lastName
// 姓名的成员属性
// 读取器
get fullName(){
return this.fistName+'_'+this.lastName
}
// 设置器
set fullName(){
// 获取后重新赋值给firstName和lastName
let names = val.split('_')
this.firstName = names[0]
this.lastName = names[1]
}
}
// 实例化对象
const person:Person = new Person('我爱','学习')
// 获取该属性成员属性
console.log(person.fullName)
// 设置该属性的数据
person.fullName = '学习_爱我'
静态成员
在类中通过static修饰的属性或者方法,就是静态属性及静态方法,也称之为静态成员
// 定义一个类
class Person{
// 静态属性
// 类中默认有一个内置的name属性
static name1:string
static constructor(){
// 此时this是实例对象,name1是静态属性,不能通过实例对象直接调用静态属性
// this.name1 = name
}
sayHi(){
console.log('我爱学习')
}
}
// 实例化对象
const person:Person = new Person()
// 通过实例对象调用的实例属性
console.log(person.name1)
// 调用的实例方法
person.sayHi()
// 通过类名.静态属性的方法来设置该成员数据
Person.sayHI()
抽象类
包含抽象方法(抽象方法一般没有任何具体内容的事件),也可以包含实例方法,抽象类不能被实例化
抽象类的作用就是为子类服务,让子类进行实例化及实现内部的抽象方法
// 定义一个抽象类
abstract class Animal{
// 抽象方法
abstract eat(){
注意!里面不能有具体实现
}
// 实例方法
sayHi(){
console.log('滚去学习')
}
}
// 定义一个子类Dog
class Dog extends Animal{
// 重新实现抽象类中的方法,此时这个方法就是当前Dog类的实例方法
eat(){
console.log('就算是狗也要学习')
}
}
// 实例化dog对象
const dog:Dog = new Dog()
dog.eat()
// 调用抽象类中的实例方法
dog.sayHi()
// 不能实例化抽象类的对象
// const ani:Animal = new Animal()
函数
封装了一些重复使用的代码,在需要的时候直接调用
// 函数声明,命名函数
function add (x:string,y;string):string{ //求和的函数
return x+y
}
// 函数表达式,匿名函数
let add2 = function (x:number,y:number):number{
return x+y
}
// 函数完整写法
const add3:(x:number,y:number) => number=function(x:number,y:number):number{
return x+y
9
}
可选参数和默认参数
// 定义一个函数
const getFullNameZ = function(firstName:string='学习',lastName:string):string{
// 判断名字是否传入
if(lastName){
return fitstName + '_' + lastName
}else{
return firstName
}
}
// 函数调用
console.log(getFullName('习学'))
可选参数:函数在声明的时候,内部的参数使用了?修饰,表示该参数可以传入也可以不传入
剩余参数(rest参数)
函数声明时剩余参数是放在所有参数最后的
// ...args:string[] 表示剩余参数,放在了一个字符串的数组中,args里面
function showMsg(str:string,...args:string)
函数重载
函数名字相同,函数的参数及个数不同
// 函数重载声明
function add(x:string,y:string):string
function add(x:number,y:number):number
// 定义一个函数
function add (x:string|number,y:string|number):string|number{
if(typeof x === 'string' && typeof y === 'string'){
return x + y // 字符串拼接
}else if(typeof x === 'number' && typeof y === 'number'){
return x + y // 数字相加
}
}
// 函数调用
// 两个参数都是字符串
console.log(add('我爱','学习'))
// 两个参数都是数字
console.log(add(10,20))
// 如果传入非法数字 如果没有上面的重载限制就会报错
console.log(add(100,'真好'))
泛型
在定义函数、接口、类的时候不能预先确定要使用的类型
// 定义一个函数传入两个参数,第一个时数据,第二个数量,作用是根据数量产生对应个数的数据,放进数组
// 定义函数
// 可以传入任意类型的数据,返回的是存储这个任意类型数据的数组
function getArr<T>(value:T,const:T):T[]{
// 根据数据和数量产生一个数组
const arr : T[]=[] // 或者const arr:Array<T>
for(let i = 0 ; i<count;i++){
arr.push(value)
}
return arr
}
const arr1 = getArr4<number>(200,3)
我敲不下去了...我得缓缓
多个泛型参数的函数
函数中有多个泛型的函数
function getMsg<K,V>(value1:K,value2:V):[K,V]{
return[value1,value2]
}
const arr1 = getMsg<string,number>('jack','100.235')
console.log(arr1[0].split(''),arr1[1].toFixed(1)) // split('')拆分字符串
泛型接口
定义接口时指定泛型类型,使用接口时再指定具体的泛型类型
// 定义一个用户类,通过类的实例对象调用相关方法可以添加多个信息对象,调用getUserId方法可以根据id获取某个指定的用户信息对象
// 定义一个泛型接口
interface IBaseCRUD<T>{
data : Array<T>
add : (t:T)=>T
getUserId : (id: number)=>T
}
class User{
id?:number // ?代表可有可无
name:string
age:number
// 构造函数
constructor(name:string,age:number){
this.name = name
this.age = age
}
}
// 定义一个类,增加和查询
class UserCRUD implements IBaseCRUD<User>{
// 用来保存多个User类型的用户信息
data : Array<User>=[]
add(user:User):User
// 产生id
user.id = Data.now() + Math.random()
// 把用户信息对象添加到data数组中
this.data.push(user)
return user
// 方法用来存储用户信息对象的
getUserId(id:number)
// 方法根据id查询指定的用户对象
getUserId(id:number): User{
return this.data.find(user => user.id === id)
}
}
// 实例化添加用户信息对象的类UserCRUD
const userCRUD : UserCRUD = new UserCRUD()
// 调用添加数据的方法
userCRUD.add(new User('jack',20))
userCRUD.add(new User('lucy',19))
console.log(userCRUD.data)
泛型类
class GenericNumber<T>{
// 默认的属性的值的类型是泛型类型
defaultValue:T
add:(x:T,y:T) => T
}
// 实例化类的对象的时候,再确定泛型的类型
const g1 : GenericNumber<number> = new GenericNumber<number>()
// 设置属性值
g1.defaultValue = 100
// 相加的方法
g1.add = function(x,y)
return x + y
基础结束