一,instanceof
1.作用
instanceof 运算符可以用来检测某个对象是否是某个类的实例
2.基础用法
// 返回判断结果 **布尔值**
实例对象 instanceof Class
二,typeof运算符
1.作用
可以通过 typeof 运算符来获取类型,他返回的是一个字符串
2.基础用法
// 前面 5 个可以正常获取到类型
console.log(typeof 123) // number
console.log(typeof '123') // string
console.log(typeof false) // boolean
console.log(typeof undefined) // undefined
function func() {
}
console.log(typeof func) // function
class Person {
name: string = 'jack'
}
// 对象 数组 null 获取到的都是 object
// 后续可以结合 instanceof 进行精确判断
const p: Person = new Person()
console.log(typeof null) // object
console.log(typeof [1, 2, 3]) // object
console.log(typeof p) // object
三,修饰符
1.作用
类的方法和属性可以通过修饰符来 限制访问
2. donly(只读)
可以用来修饰属性(字段),修饰之后外部只可以取值,无法修改
3. private(私有)
private修饰的成员不能在声明该成员的类之外访问,包括子类
4. protected(受保护)
protected修饰符的作用与private修饰符非常相似,不同点是protected修饰的成员允许在派生类(子类)中访问
5. public(公共)
public修饰的类成员(字段、方法、构造函数)在程序的任何可访问该类的地方都是可见的。
6.总结
| 修饰符名 | 作用 | 适用范围 | 访问限制 |
|---|---|---|---|
| readonly | 只读 | 属性 | 无限制 |
| private | 私有 | 属性、方法 | 类内部可以访问 |
| protect | 保护 | 属性、方法 | 类及子类可以访问 |
| public | 公共 | 属性、方法 | 无限制 |
四,剩余参数
1.作用
通过剩余参数的语法,我们可以将 函数 或 方法 中一个不定数量的参数表示为一个数组
2.用例模板
// **剩余参数只能写在最后一位**
function 函数名(参数1,参数2,...剩余参数数组){
// 逻辑代码
// 剩余参数之前的参数 挨个获取即可
// 剩余参数:以数组的形式获取
}
3.用例实现
function sum(numA:number,numB:number,...theArgs:number[]) {
let total = numA+numbB;
for (const arg of theArgs) {
total += arg;
}
return total;
}
console.log(sum(1, 2, 3).toString()) // 6
console.log(sum(1, 2, 3, 4).toString()) // 10
五,展开
1.用法
只能用在数组上,常用语进行数组的合并,以及将一个数组追加到一个空数组中
2.基础用法实例
const numArr1: number[] = [1, 2, 3, 4]
const numArr2: number[] = [5, 6, 7]
// 合并到一起
const totalArr: number[] = [...numArr1, ...numArr2]
//输出:1,2,3,4,5,6,7
六,简单数据类型,复杂数据类型
1.基本数据类型
number string boolean undefine null
2.复杂数据类型(引用数据类型)
Object Funnction Array
3.内存中堆栈空间
1.栈:访问速度快,存放基本数据类型
2.堆:存储容量大,用于存放引用数据类型
4.两种数据类型的存储方式
基本类型:变量名,变量值都存储在栈中,访问速度快
引用类型:变量名,内存地址存放在栈中,变量值存放在堆中
注意
class Person {
name: string = ''
constructor(name: string) {
this.name = name
}
}
const p1: Person = new Person('jack')
const p2: Person = p1
p2.name = 'rose'
//p1,p2值为rose
七,接口补充
接口定义及实现
interface 接口1{
属性1:类型
}
interface 接口2 extends 接口1 {
属性2:类型
}
class 类 implements 接口{
// 必须实现 接口中定义的**所有**属性、方法,否则会报错
}
八,泛型
1.作用
泛型在保证类型安全(不丢失类型信息)的同时,可以让函数等与多种不同的类型一起工作,灵活可复用 通俗一点就是类型是可变的!
2.泛型方式
1.泛型函数
/* 泛型函数演示:
* 1. 泛型函数语法:
* function 函数名称<T>(形参:T) {
* let tmp:T = 形参
* return [形参] // T[]
* }
function type<T>(args: T) {
return [args]
}
let a=type(100) 输出:100
let b=type<boolean>(false) 输出:false
let c=type<string>('false') 输出:false
let d=type<string[]>(['false','数组']) 输出:['false','数组']
let e=type<number[]>([100,11]) 输出:[100,11]
2.泛型约束
1.联合类型
// 泛型函数getData的T约束只能传入数字和字符串这两个类型的参数
function getData<T extends number | string>(args:T){
return [args]
}
getData('ok') // ✔️
getData(100) // ✔️
getData(true) // ❌不接受布尔类型
2.枚举类型
// 约束T只能是Color枚举中的一个值
function getColor<T extends Color>(color: T) {
return color
}
getColor(Color.White)// ✔️
getColor('White')// ❌
3.接口类型
// 定义接口
interface iPerson {
name: string
}
// 泛型函数T被iPerson约束
function getData<T extends iPerson>(args: T) {
return args
}
let obj: iPerson = { name: '张三' }
let arr = [1,2,3]
getData(obj) // ✔️
getData(arr) // ❌
3.多个泛型参数
* 泛型函数多个参数以及多个参数的类型约束
* 1. 多个参数语法:
* 函数名<T1,T2,...>(参数1:T1,参数2:T2,...) {}
*举例:
function funA<T1, T2>(a1: T1, a2: T2) {
console.log('a1=', a1, 'a2=', a2)
}
*
* 2. 多个参数类型约束语法:
* 函数名<T1 extends 类型,T2 extends 类型,....>()
* 函数名<T1 extends 类型,T2 ....>()
*
* 类型可以是:基本类型和复杂类型,联合类型,枚举
function type<t1 extends string,t2>(name:t1,other:t2){
console.log(name,other)
}
type('张三',10)
type('张三','男')
type('颤三',true)
4.泛型接口
interface data<t>{
name:string
age:number
date:t
}
let obj:data<Number[]>={
name:'张三',
age:12,
date:[12,14] //number[]形式
}
let obj1:data<string[]>={
name:'三',
age:12,
date:['12','14'] //string[]形式
}
console.log(JSON.stringify(obj)) //输出 {"name":"张三","age":12,"date":[12,14]}
console.log(JSON.stringify(obj1)) //打印数组数据 {"name":"三","age":12,"date":["12","14"]}
九,工具类型(简化代码)
1、Partial<类型名>
作用:将必选参数的所有属性转化为可选参数
1.基础语法
type 新类型 = Partial<接口>
type 新类型 = Partial<类>
// 后续使用新类型即可
2.基础用例
class Person {
name: string = ''
age: number = 0
friends: string[] = []
}
type ParPerson = Partial<Person>
// 因为都是可选的,可以设置为空对象
let p: ParPerson = {}
2.Readonly<类型>用法同上
作用:将所有可选属性方法等转化为必选属性
3.Readonly<类型>用法同上
作用:将所有属性设置为只读(只能访问,修改会报错)
4.Record<Keys,Type>
作用:构造一个对象类型,其属性键为Keys,属性值为Type。该实用程序可用于将一种类型的属性映射到另一种类型。
@State person = {'name':'张三'} // ❌这样定义报错 -> 因为没有使用interface指定对象类型
// 如果不想定义interface,就可以直接使用Record<Key,Value>来指定对象类型即可
@State person:Record<string,string> = {'name':'张三'} // ✔️
✨✨注意:{}对象的属性名类型要对应Record<Key类型,value类型> 中的Key类型,属性值对应value类型
console.log(person['name'].toString()) //输出张三
十,空安全
1.作用
默认情况下,ArkTS中的所有类型都是不可为空的。如果要设置为空,需要进行特殊的处理,并且在获取 可能为空的值的时候也需要特殊处理
2.联合类型设置为空
let x: number = null // 编译时错误
let y: string = null // 编译时错误
let z: number[] = null // 编译时错误
解决办法:
// 通过联合类型设置为空
let x: number | null = null
x = 1 // ok
x = null // ok
3.非空断言运算符
后缀运算符! 可用于断言其操作数为非空。
应用于空值时,运算符将抛出错误。否则,值的类型将从T | null更改为T:
let x: number | null
let y: number
y = x + 1; // 编译时错误:无法对可空值作加法
y = x! + 1; // 通过非空断言,告诉编译器 x不为 null
4.空值合并运算符
class Person {
name: string | null = null
getName(): string {
// return this.name != null ? this.name : ''
// 等同于 如果 name不为空 就返回 name 反之返回 ''
return this.name ?? ''
}
}
5.可选链
作用
在访问对象属性时,如果该属性是undefined或者null,可选链运算符会返回undefined。
interface iPerson{
name:string
dogAge?:number // 人有宠物狗也有可能没有宠物狗,所以狗的年龄dogAge为可选
}
//定义人对象
let person:iPerson = {name:'明明'}
// 打印人拥有的宠物狗年龄
console.log(person.dogAge.toString()) // 报错❌
// 解决方案1:使用if判断来判断如果为空就不执行,编译器认为这个代码安全,运行执行✔️
if(person.dogAge){
console.log(person.dogAge.toString())
}
// 解决方案2:使用?可选链来断定可能为空,编译器认为这个代码安全,运行执行✔️
console.log(person.dogAge?.toString())