0.ArkTS基础语法

打印日志:console.log(‘消息说明’,‘打印的内容’)

对象等复杂数据,需要日志打印需要JSON.stringify()转换

文档中心

项目:

HarmonyOS NEXT 面试通
守护助手APP项目实战教程_哔哩哔哩_bilibili 鸿蒙守护助手-黑马程序员_v1.0

项目代码仓库:

美蔻商城 面试通 鸿蒙守护助手
微信聊天 小时达 小时达-快递项目(hap+har).md

变量

基础数据类型

let:表示全局变量

  • string 字符串, ‘’ 和 ""都可以
  • number 数字,Number(数字/变量).toFixed(数字)保留几位小数
  • boolean 布尔(真、假)
let 变量名: 类型 = 值
Number(数字/变量).toFixed() //保留两位小数
// 字符类型,'' 或 "" 包裹
let title: string = '巨无霸汉堡';
console.log('字符串title',title);

//数字
let age: number = 18
console.log('年龄age:',age);

//布尔
let islogin: boolean = true
console.log('是否登陆成功:',islogin)

//修改
title = 'xinzai'
console.log('字符串title',title);
age = 90
console.log('年龄age:',age);
islogin = false
console.log('是否登陆成功:',islogin)

状态变量

自动更新视图更新也就是改变会引起 UI 的渲染刷新

@State 变量名: 变量类型 = 值

@State msg3: string = 'Hello World'

联合类型

灵活的数据类型,它修饰的变量可以存储不同类型的数据

let 变量: 类型1 | 类型2 | 类型3 = 值
let judge : number | string = 100
judge = 'A'
console.log(judge) //A

//变量值限定在一组数据范围内选择
let gender: 'man' | 'woman' | 'secret' = 'secret'
console.log('性别:',gender)

枚举类型

约定变量只能在一组数据范围内选择值

enum 枚举名 {  
常量1 = 值,
常量2 = 值,
......
}
//定义枚举
enum ThemeColor{
//常量列表
Red = '#ff0f29',
Orange = '#ff7100',
Green = '#30b30e'
}
//给变量设定枚举类型
let color: ThemeColor = ThemeColor.Red
console.log('颜色',color)

常量

用来存储不可变数据

const 常量名: 类型 = 值
const PI: number = 3.14
console.log("PI",PI);

运算符

一元运算符单独一行的时候前加和后加效果都一致

算数运算符 作用 赋值运算符 作用 一元运算符 作用
+ += 加等于 ++i 先加后使用
- -= 减等于 i++ 先使用后加
* *= 乘等于 –i 先减后使用
/ /= 除等于 i– 先使用后减
% 取余 %= 取余等于
比较运算符 作用 逻辑运算符 作用
> 大于 && 与,都真才真
>= 大于等于
< 小于 ! 非,取反
<= 小于等于 != 判断不等于
== 判断相等

字符串

字符串拼接

用于拼接字符串和变量

let name: string = '小明'
console.log('简介信息', '名字是' + name)

模板字符串

更适合于 多个变量 的字符串拼接

`...${变量名1}.....${变量名2}.....`
let name: string = 'xinzai'
let age: number = 18
console.log('信息:',`名字是${name},年龄是${age}`)

类型转换

//字符串转数字
Number(变量名) //字符串 直接转数字,转换失败返回NaN(字符串中包含非数字)
parseInt(变量名) //去掉小数部分 转数字,转换失败返回NaN
parseFloat(变量名) //保留小数部分 转数字,转换失败返回NaN
//数字转字符串
变量名.toString() //数字直接转字符串
变量名.toFixed() //四舍五入转字符串,可设置保留几位小数
let num: string = '1.1'
let num1: string = '1.1a1'
console.log('值:',Number(num)) //1.1
console.log('值:',parseInt(num)) //1
console.log('值:',parseFloat(num)) //1.1
console.log('值:',Number(num1)) //NaN

let num: number = 1.12523
console.log('值:',num.toString()) //'1.12523'
console.log('值:',num.toFixed()) //'1'
console.log('值:',num.toFixed(2)) //'1.13',保留两位小数

数组

下标从零开始

let 数组名: 类型[] = [数据1, 数据2,...]
let 数组名:Array<类型> = [0,1,2,6]
let 数组名 = Array(数字).fill(填充内容); //数字是创建长度多少的数字,填充内容可字符串或数字
let numList2:Array<number> = [0,1,2,6]
let names: string[] = ['nihao','xinzai','bs']
console.log('数组:',names)
console.log('1:',names[1])

数组的操作

任意位置 增加 或删除

数组名.splice(起始位置, 新增/删除个数, 新增元素1, 新增元素2, ......)	//从起始位置开始增加或删除
数组名.length //数组长度
//增加
数组名.unshift(数据1, 数据2, 数据3, ...) //从开头加
数组名.push(数据1, 数据2, 数据3, ...) //从结尾加
数组名.push(...数组名1) //将数组名1的数组提出来后合并到数组名的数组后面
//删除
数组名.shift() //从开头删
数组名.pop() //从结尾删
//筛选,符合条件的保留创建新的数组
//item:arr数组中的数据项,index:arr数组中的数据项索引
数组名.filter((item, index) => 条件筛选)
name.splice(1,1,'123')
console.log('任意新增/删除:',name) //xinzai,123,wfeng,xiaowng
console.log('长度:', name.length) //4
//增加
name.unshift('123','321')
console.log('增加:',name) //123,321,xinzai,jueni,wfeng,xiaowng
name.push('123','321')
console.log('增加:',name) //xinzai,jueni,wfeng,xiaowng,123,321
//删除
name.shift()
console.log('删除:',name) //jueni,wfeng,xiaowng
name.pop()
console.log('删除:',name) //xinzai,jueni,wfeng
//筛选
const fruits = ["apple", "banana", "grape", "orange"];
const filteredFruits = fruits.filter(fruit => fruit.includes("ap")); //筛选数组中值为ap

遍历数组

//方式一:普通for循环遍历输出
let name: string[] = ['xinzai','lisi','wangwu']
//方式二
for (let item of 数组名) {} //item: 声明的一个变量, 用来在循环的时候接收 每一个数组元素
for (let i = 0;i < name.length;i++){
console.log('名字',name[i])
}

let name: string[] = ['xinzai','lisi','wangwu']
for (let item of name){
console.log('名字',item)
}

对象数组

//定义接口
interface 接口名{
//属性
}
//定义对象数组
let 对象数组名: 接口名[] = [{ 属性名1: 值, 属性名2: 值, ... }, ...]
//访问
对象数组名[下标].属性值
//需要修改数据,要整个对象都修改,不能修改对象中的一个数据
this.对象数组名[下标值] = {
属性名1: 值
属性名2: 值
}
interface  Person{
stuId: number
name: string
}
let pArr: Person[] = [{stuId: 1,name:'小红'},{stuId: 2, name:'xinzai'}]
console.log('数',pArr[1].name)
this.images[this.random] = {
url: `app.media.img_0${this.random}`,
count1: this.images[this.random].count1 + 1
}

函数(function)

function:表示全局

//定义函数
function 函数名(形参1: 类型, 形参2: 类型,...): 返回值类型{
return 返回值
}
//调用函数
let 变量名: 类型 = 函数名(实参1,实参2,...)
//定义函数
function test(){
console.log('五角星','*')
console.log('五角星','**')
console.log('五角星','***')
console.log('五角星','****')
}
//调用函数
test()

function buy(price: number,num: number){
let result: number = price*num
return result
}
console.log('价格:',buy(10,3));

箭头函数

let 函数名 = (形参1: 类型, 形参2: 类型,...) => {  
// 函数体
return 返回值
}
函数名(实参1,实参2,...)
let num_Price = (price: number, num: number)=>{
let result: number = price*num
return result
}
console.log('总价格:', num_Price(3,2))

重复执行函数文档中心

setInterval(() => {
//执行的操作,第一次执行也要等待时间
}, 延迟的毫秒数);
setInterval(() => {
console.log('do every 1s.');
}, 1000);

创建定时器函数文档中心

setTimeout(() => {	//不带参数
//执行的操作,只执行一次
}, 延迟的毫秒数);
setTimeout(() => {
console.info('delay 1s');
}, 1000);

剩余参数和展开运算符

将 函数 或 方法 中一个不定数量的参数表示为一个数组

function 函数名(参数1, 参数2, ...数组名:类型[]){
}
function num(a1: number,a2: number,...theArgs:number[]){
let count = a1+a2
for(const flags of theArgs){
count += flags
}
console.log('值',count)
return count
}
num(1,2,3)

展开运算符只能用在数组上(一般用在合并上)

const 数组名: 数据类型[] = [...数据名1, ...数组名2]
const a1: number[] = [1,2,3,4,5,6]
const a2: number[] = [3,4,6,17,27]
const num: number[] = [...a1,...a2]
console.log('结果',num)

接口

//定义接口约束对象中变量及函数的类型
interface 接口名{
属性1: 类型1
属性2: 类型2
属性3: 类型3

方法名: (参数: 类型) => 返回值类型
}
interface Person{
//声明属性类型
name: string
age: number
weight: number

//声明方法
dance: () => void
sing: (sing: string) => void
}

接口继承

interface 接口2 extends 接口1 {
//属性2:类型
}
interface IAnimal{
name: string
age: number
}
interface IDog extends IAnimal{
color: string
}
let dog1: IDog = {
//不仅要实现IDog子接口还需要实现父接口
name: 's',
age: 12,
color: 's'
}

接口实现

class 类 implements 接口{
// 必须实现 接口中定义的 属性、方法,
// 否则会报错
}
interface IDog {
name: string
age: number
color: string
jump: () => void
}

class Test implements IDog {
name: string
age: number
color: string

constructor(name: string, age: number, color: string) {
this.name = name
this.age = age
this.color = color
}

jump = () => {
console.log('名字',this.name)
}
}
let test:Test = new Test('x',12,'s')
test.jump()

接口自动转 class 类

若安装存在网络以及权限问题,自行百度解决

node -v												//查看node版本,需在v18.20.1及以上
npm i -g interface2class //安装
i2c -V //检测安装版本
//转换使用,工程在对应的est文件中右键“打开范围”选择Terminal
i2c .\转换的文件

对象

存储多个不同数据的容器,定义的interface可以给不同的对象重复使用,但对象需要的是相同的结构类型

let 对象名称: 对象结构类型 = {
属性名1: 值,
属性名2: 值,

方法名: (形参名1: 类型,...) =>{
//方法体
}
}

//调用属性及方法
对象名.属性名1
对象名.方法名1()
//定义对象
let ym: Person = {
name: '李四',
age: 19,
weight: 88,

dance: () =>{
console.log('nihao','xinzai')
},
sing: (song: string) => {
console.log('唱歌:',song)
}
}
//调用对象属性
console.log('名字',ym.name)
console.log('年龄:',ym.age)
//调用对象方法
ym.dance()
ym.sing('奇迹')

分支语句

if

let score: number = 66
if (score >= 90){
console.log('优秀')
}else if (score >= 70){
console.log('良好');
}else {
console.log('不及格') //不及格
}

switch

let m: number = 2
switch (m){
case 1:
console.log('1')
break
case 2:
console.log('2') //2
break
default :
console.log('其他')
}

三元条件表达式

//当变量名1 的值大于 变量名2 的值,返回变量名1 的值否则返回变量名2 的值
变量名1 > 变量名2? 变量名1 : 变量名2
let num1: number = 5
let num2: number = 10
let res: number = num1 > num2 ? num1 : num2 // 返回较大值
console.log('结果是', res) //10

循环语句

for

for (let i: number = 0; i < 5; i++) {
console.log('for', '重复执行的代码')
}

for (const arg of 数组名) {
console.log('值', 'arg')
}

while

while (条件) {
条件成立重复执行的代码
}

let i: number = 1
while (i < 5) {
console.log('while~i', '重复执行的代码')
i++
}

随机数生成

Math.random()	//默认0~1
//需要0~5,需要乘6

Math.floor() //向下取整

Class类

用于 创建对象 模板。同时类声明也会引入一个 新类型,可定义其 实例属性、方法 和 构造函数

// 类名 首字母大写(规范)
class 类名{
// 1. 实例属性(字段)
字段名.类型 = 值 //没有构造函数时必须有初始化值
字段名?:类型
// 2. 构造函数,不同实例 有不同的 字段 初始值,在实例化对象时将参数传进构造函数将字段初始化
constructor(形参名1: 类型, 形参名2: 类型) { //也可以传对象
this.属性名1 = 形参1
this.属性名2 = 形参2
}
// 3. 方法
方法名(参数...): 返回值类型{
// 逻辑...
// 可以通过 this 获取实例对象
}
}
// 使用类 实例化对象 基于类 创建对象
let 实例化类名: 类名 = new 类名()
let 实例化类名: 类名 = new 类名(值1 ,值2) //传入的参数必须和构造函数形参顺序一致
class cat{
name: string = '小黑'
food?: string
}
let mycat: cat = new cat()
console.log('名字',mycat.name)
mycat.food = '小黄鱼'
// ?. 可以保证若food没有赋值不会报错,没有赋值显示undefined
console.log('食物',mycat?.food)
//有构造函数
class Food{
name: string
price?: number

constructor(name: string, price: number) {
this.name = name
this.price = price
}
}
let mycat: Food = new Food('西蓝花',20)
console.log('名字',mycat.name)
console.log('食物',mycat.price)

//扩展,使用接口,构造函数传入对象
interface IFood{
name: string
price: number
}
class Food{
name: string
price?: number

constructor(paramsObj: IFood) {
this.name = paramsObj.name
this.price = paramsObj.price
}
style(name:string){
console.log(`你好${name}`,`菜名${this.name}`)
}
}
let myfood: Food = new Food({
//此时传入的参数可以不用按照构造函数参数的顺序
name: '菜心',
price: 20
})
console.log('名字',myfood.name)
console.log('食物',myfood.price)
myfood.style('xinzai')

静态属性和静态方法

给类添加 静态属性、方法,通过类名访问不需要 new

static 静态属性名: 类型 = 值
static 静态方法名(参数): 返回值类型{
}
class Roboot{
static version: string = 'v2.0'
static getRomdom(): number{
return Math.random()
}
}
console.log('版本',Roboot.version)
console.log('随机数',Roboot.getRomdom())

继承

子类可以继承父类的方法和属性,super 可以访问父类的实例字段、实例方法和构造函数

class 子类 extends 父类{
// 自己的字段(属性)
// 自己的方法
// 可以重写父类方法
}
class Person{
name: string
age: number

constructor(name: string,age: number) {
this.age = age
this.name = name
}
sayHi(){
console.log('大家好',this.name,this.age)
}
}
class Student extends Person{
worker: string = '学习' //子类自己的属性

constructor(name: string,age: number, worker: string) {
//子类无法继承父类构造方法,需要类似重写重新调用
super(name,age)
this.worker = worker //初始化子类属性
}
//重写父类方法
sayHi(): void {
super.sayHi() //调用父类的方法
console.log('hello', this.name,this.age)
}
}
let student: Student = new Student('李四',19,'学习')

检测实例

instanceof 检测某个对象是否是某个类的实例

class Person{
}
class Student extends Person{
}

let student: Student = new Student()
console.log('判断结果', student instanceof Person)

let temp: number[] = []
console.log('判断结果',temp instanceof Array) //判断变量是否是数组

修饰符

readonly:只可以取值,无法修改

private:修饰的成员只能在本类访问,不能在声明该成员的类之外访问, 包括子类

protected:与private修饰符非常相似,不同点protected修饰的成员允许在 派生类(子类)中访问

public:任何地方都可以访问,省略不写默认为 public

readonly legs: number = 4

class 类{
private 属性:类型
private 方法(){}
}

class 类{
protected 属性:类型
protected 方法(){}
}

泛型

让【函数】等, 与多种【不同的类型】一起工作,灵活可复用

泛型函数

类型是 可变 的

function 函数名<泛型参数名>(形参名1: 泛型参数名) : 泛型参数名{
}
//调用,类型传了什么类型,形参和返回值类型都是同样的类型
函数名<类型>(实参)
函数名(实参) //调用时也可以不用显式写出类型,会根据输入的参数判断

function fn<T>(name: T): T {
return name
}
console.log(fn('n'))
console.log('zhi',fn<number[]>([1,2,3,45,5]))

进阶

function fn<T>(s: T[]): T[] {
return s
}

function fn1<T>(s: T[]): T {
return s[s.length-1]
}

console.log('值', fn<Number>([1, 2, 3, 4, 5]).length)
console.log('值', fn<string>(['1', '2', '3', '4']).length)
console.log('值', fn1<string>(['1', '2', '3', '40']))

多个泛型参数

function fn<T1,T2> (parm1:T1,parm2:T2){
console.log('z1',parm1)
console.log('z2',parm2)
}
fn('aa',123)

泛型约束

interface 接口{
//属性: 类型
}
function 函数<Type extends 接口>(){} // 传入的类型必须要有 接口中的属性

interface Ilength {
length: number
}
function fn<T extends Ilength>(param: T): T {
return param
}
//传入的参数必须有接口中length属性
console.log('值', fn('132'))

class Desk {
length: number = 2
}
let d = new Desk()
fn<Desk>(d)