学习中遇到的ArkTs知识点

296 阅读1分钟

输出语句

写法:console.log("消息内容","消息内容")

认识和存储数据

认识数据

简单数据类型

number,string,boolean,undefined,null

复杂数据类型

Array,Object,Function

数据的存储

变量和常量

变量:专门用来存储数据的容器(可变)

// let 变量名: 类型 = 值
let  price:number=99
price=100//可以修改

常量:用来存储数据 (不可变)

写法:const 常量名: 类型 = 值

const price:number=99
price=100//不可修改,报错

命名规则

① 只能包含数字、字母、下划线、$,不能以数字开头

② 不能使用内置关键字或保留字 (比如 let、const)

③ 严格区分大小写

内存中的堆栈空间

说到了数据的存储,那么常量和变量存储在哪里呢

首先我们来了解堆和栈

他们都是内存中存储数据的空间

  1. 栈:访问速度快,基本数据类型存储在里面
  2. 堆:存储容量大,引用数据类型存储在里面

再深入了解存储原理

基本数据类型的存储:

直接存储在栈空间中

引用数据类型:

  1. 栈:存放内存地址(变量在堆中的地址)
  2. 堆:存放变量的值

处理数据

字符串拼接

let name: string = '小明'
let age: number = 18
// 1. 加号拼接
console.log('简介信息', '名字是' + name, '年龄是' + age)

模板字符串

let name: string = '小明'
let age: number = 18

// 2. 模板字符串
// 简介信息:姓名是小名,今年18岁了
console.log(`简介信息:姓名是${name},今年${age}岁了`)

类型转换

字符串转数字

Number():将字符串转换为数字,失败返回NaN(字符串里含有非数字)

let str1: string = '1.1'
let str2: string = '1.9'
let str3: string = '1.1a'

console.log('数字是', Number(str1))  // 1.1
console.log('数字是', Number(str2))  // 1.9
console.log('数字是', Number(str3))  // NaN

数字转字符串

  • toString()
let num1: number = 1.1
let num2: number = 1.9

console.log('字符串是', num1.toString()) // '1.1'
console.log('字符串是', num2.toString()) // '1.9'
  • toFixed():四舍五入转字符串,可设置保留几位小数
let num1: number = 1.1
let num2: number = 1.9
let num3: number = 1.9152

console.log('字符串是', num1.toFixed())  // '1'
console.log('字符串是', num2.toFixed())  // '2'
console.log('字符串是', num3.toFixed(2))  // '1.92' 

状态管理

如果要构建一个动态的、有交互的界面,就需要引入”状态“的概念

基本概念

状态变量:被状态装饰器装饰的变量,状态变量值的改变会引起UI的渲染更新**。**

常规变量:没有被状态装饰器装饰的变量,通常应用于辅助计算。它的改变永远不会引起UI的刷新。

示例:

// 常规变量:不会引起UI更新
let name: string = '小明'

@Entry
@Component
struct Index {
  // 状态:变量值改变会引起UI更新
  @State
  hi: string = 'hello'

  build() {
    Column(){
      Text(name)

      // 通过 this 找到对应的状态
      Text(this.hi)
    }
  }
}

注意:

  1. 状态变量必须设置类型
  2. 状态变量必须设置初始值

数组

数组是一个容器,可以存储多个数据

let 数组名:数据类型[]=[数据1,数据2,数据3]

获取数据元素

console.log("数据元素",数组名[数组下标])
//数组的下标可以理解在数组中的排列数据(数组的元素在内存是顺序存储的),不过下标是从0开始的
let name:sting[]=["小花""小帅""丧彪"]
console.log("获取整个数组元素",name)
console.log("获取第一个元素",name[0])

数组的操作

操作语法查找数组名[下标]修改数组名[下标] = 新值增加数组名.push(数据1, 数据2, ...)、 数组名.unshift(数据1, 数据2, ...)删除数组名.pop()、数组名.shift()任意位置增加或删除数组名.splice(操作的起始位置, 删除的个数, 新增1, 新增2, ......)

增加

  • 开头添加:
    • 语法: 数组名.unshift(数据1, 数据2, 数据3, ......)
    • 返回值: (返回值指的是操作后的结果) 增加数据之后的元素个数,即数组的新长度
    • 是否修改原数组: 是
  • 结尾添加:
    • 语法: 数组名.push(数据1, 数据2, 数据3, ......)
    • 返回值: 增加数据之后的元素个数,即数组的新长度
    • 是否修改原数组: 是
    •       let num: number[] = [1]
            num.unshift(1, 2, 3) //[1,2,3,1]
            console.log("", num);
      
let num: number[] = [1] 
num.push(1, 2, 3) //[1,1,2,3]
console.log("", num);

删除

  • 语法: 数组名.shift()
  • 返回值: 删除的数据
  • 是否修改原数组: 是
  • 结尾删除:
    • 语法: 数组名.pop()
    • 返回值: 删除的数据
    • 是否修改原数组: 是
    •       let names: string[] = ['小红', '小明', '大强']
      
            // pop(): 结尾删除
            names.pop()
      
            // shift(): 开头删除
            names.shift()
      
            console.log('数组names', names)
      

任意位置删除、增加

  • 语法: 数组名.splice(起始位置, 删除的个数, 新增元素1, 新增元素2, ......)
    • 注意: 如果不写该参数,代表从开始的位置起,删除往后所有的元素
  • 返回值: 删除的元素组成的新数组
  • 是否修改原数组: 是
let names: string[] = ['小红', '小明', '大强']

names.splice(1, 1, 'jack')

console.log('数组names', names)

函数

基本使用

function 函数名()
{
函数体
}
//调用
函数名()

示例:

function fun(){

console.log("hello")
}
//函数被调用是执行函数体 
fun()

完整写法:

function 函数名(需要处理的数据) {
  编写代码对数据进行处理
  return 处理后的结果
}

let 变量名: 类型 = 函数名(实际要处理的数据)
//需要处理的数据=形参
//实际要处理的数据=实参

这里我们要了解实参、形参的区别

  • 实参:真实数据(函数调用时候的传入的真实数据)
  • 形参:形式上的参数(函数定义时候写的参数)
  • 同时形参的变化,不会影响实参

函数的可选参数

函数在定义的时候,设置了形参入口,但是在调用的时候并不是任何时候都需要传入实参数据,为了避免报错,我们可以将形参设置为可选参数, 或者给形参设置一个默认值

  • 语法: 形参 -- name?: Type
    • name: 形参名称
    • ? : 表示可有可无
    • Type: 接收数据的类型
    •       function sayHi(params?: string) {
            //如果没有传入实参数据输出'hello',传入了实参数据输出params
              console.log('打招呼语', params || 'hello')
      
              // undefined
              console.log('打招呼语', params)
            }
      
            sayHi('你好')
            sayHi()
      

可选参数 -- 默认值

function cale(x:number,y:number)
{
return x+y
}
//这里需要传入两个数据,少一个就报错
function cale(x:number,y:number=2){
return x+y
}
//这里y有一个值,那么就可以只传入x的值
//注意默认值要写在后面,也就是两个形参,一个有默认值,那么这个形参要在没有默认值的后面

箭头函数

函数的另一种写法

let 函数名 = (形参1: 类型, 形参2: 类型) => {
  // 函数体
  // 1. 计算过程
  // 2. 返回结果
  return 计算的结果
}

函数名(实参1, 实参2)

对象

作用:用于描述一个物体的特征和行为

对象:是一个可以存储多个数据的容器。

键值对:属性名: 属性值

对象的定义

//1.定义接口
interface 接口名 {
  属性1: 类型1
  属性2: 类型2
  属性3: 类型3
}

interface Person {
  name: string
  age: number
  weight: number
}
//基于接口,定义对象
let hmbb:Person={
name:"海绵宝宝",
age:999,
weight:999
}
//使用 对象名.属性名
hmbb.name
hmbb.age

对象-方法

方法作用:描述对象的具体行为

interface 接口名称 {
  方法名: (参数:类型) => 返回值类型
}
let 对象名:接口名称={
方法名:(参数:参数类型)={}
}

示例:

//定义接口
interface hmbb{
catch:()=>void
}
//定义对象
let hm:hmbb={
catch:()={
console.log("抓到了")
}
}
//使用 // 对象名.方法名(参数)
hm.catch()

对象数组

定义对象数组

// 1. 定义接口
interface Person {
  stuId: number
  name: string
  gender: string
  age: number
}

// 2. 根据接口定义对象数组
let students: Person[] = [
  {stuId: 1, name: '小红', gender: '女', age: 18},
  {stuId: 2, name: '小明', gender: '男', age: 19},
  {stuId: 3, name: '大强', gender: '男', age: 18}
]
//一个{stuId: 1, name: '小红', gender: '女', age: 18}可以看成一个数组元素
//就是一个对象是数组元素

访问元素:

// 3. 访问属性 数组名[下标].属性名
console.log('小红的年龄是', students[0].age)

// 4. 遍历对象数组
for (const item of students) {
  console.log('学生姓名是', item.name)
}

注意:

即使使用了@state修饰了对象数组,修改了对象数组的值UI也不会发生变化

可以使用splice对数组来操作

常用内置对象

Math对象

Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法, Math 用于 Number 类型数据的处理.

方法说明Math.random()返回一个 0 到 1 之间的伪随机数。Math.ceil(x)返回大于一个数的最小整数,即一个数向上取整后的值。Math.floor(x)返回小于一个数的最大整数,即一个数向下取整后的值。Math.round(x)返回四舍五入后的整数。Math.abs(x)返回一个数的绝对值Math.max([x[,y[, …]]])返回零到多个数值中最大值。Math.min([x[,y[, …]]])返回零到多个数值中最小值。

Date对象

这里需要用到类的知识

ArkTS 中另外一个常用的内置对象 Date,他可以用来创建、解析、操作日期和时间

实例方法:

使用 Date 对象首先需要通过 new 操作符进行实例化

方法名作用说明getFullYear获取年份 4 位数年份getMonth获取月份取值 0-11getDate获取日期 月份中的日期getHours获取小时无getMinutes获取分钟无getSeconds获取秒无getDay获取星期周日为 0

// 获取当前日期
const date1: Date = new Date()

// 获取指定日期
// ISO 8601 格式(YYYY-MM-DDTHH:mm:ss.ssZ)中间用 T 分隔
const date2: Date = new Date('1995-01-01T01:11:00')
// Unix时间戳 是指从1970年1月1日(UTC)开始到现在经历的时间(毫秒)
const date3: Date = new Date(1706170405708)

静态方法:

方法名作用说明now获取当前时间时间戳

// 大伙执行的时候 即可获取到时间戳啦~
console.log(Date.now()+'')

分支语句

  • 表达式: 可以被求值的代码,并将其计算出一个结果
  • 语句: 一段可以执行的代码,是一个行为,例如分 支语句和循环语句

if分支

单分支:

if(表达式){
//条件执行的代码
}
//表达式为True是执行,为false不执行
  • 小括号内的结果若不是布尔类型时,会发生类型转换为布尔值

多分支:

if(表达式1){}

else if(表达式2){
}
else{
}
//满足的执行,否则执行else里的代码

switch语句

switch (表达式) {
  case1:
    与值1匹配执行的语句
    break
  case2:
    与值2匹配执行的语句
    break
  default:
    以上都未成功匹配执行的代码
}
  • 如果没有break语句,则执行switch中的下一个label对应的代码块
  • 一般不常用

条件表达式

条件表达式又叫三元表达式

重点:这里用好可以减少代码量

 // 条件 ? 条件成立执行的表达式 : 条件不成立执行的表达式

let num1: number = 5
let num2: number = 10

// 返回较大值
let res: number = num1 > num2 ? num1 : num2
console.log('结果是', res)

条件渲染

ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用ifelseelse if渲染对应状态下的UI内容。

ifelse if后跟随的条件语句可以使用**状态变量,**状态变量值变化时,条件渲染语句会进行更新

也就是说可以搭配状态管理的知识点来引起UI的变化

条件渲染示例:

@Entry
@Component
struct Index {
  @State
  counter: number = 1

  build() {
    Column() {
      if (this.counter == 1) {
      Text('1')
      } else if (this.counter == 2){
        Text('2')
      } else {
        Text('any')
      }

      // 单击按钮,切换显示 Text
      Button('切换')
        .onClick(() => {
          this.counter ++
        })
    }
  }
}

循环语句

while循环

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

示例:

/*
while (true) {
  console.log('while', '重复执行的代码')
}
*/

// 指定循环次数
let i: number = 1
while (i < 5) {
  console.log('while~i', '重复执行的代码')
  i++
}

在示例当中当i的值是变动的,当i=5时循环停止,那如果他的值不变呢,循环就不会停止。那一个合格的循环语句该怎么写呢

循环三要素

  1. 初始值(变量)
  2. 循环条件
  3. 变化量(变量计数,自增或自减)

for循环

for (初始值; 条件; 变化量) {
  重复执行的代码
}

退出循环

作用:满足指定条件退出循环的方式

  • break:终止循环
  • continue: 退出当前一次循环的执行,继续执行下一次循环

当循环到想要的结果时,之后的没必要执行,使用break、continue可以优化代码

遍历数组

  • 语法: for (let item of 数组名) {}
    • for ... of : 在 ... 之中 进行循环
    • item: 声明的一个变量, 用来在循环的时候接收每一个数组元素
    •       let names: string[] = ['小红', '小明', '大强']
      
            /*for(let i = 0; i < names.length; i++) {
              console.log('名字是', names[i])
            }*/
      
            for (const item of names) {
              console.log('for...of...名字是', item)
            }
      

类用于创建对象的模板,他们用代码封装数据以处理数据,同时类声明也会引入一个新类型,并定义其字段方法构造函数

// 类名 首字母大写(规范)
class 类名{
  // 字段
  
  // 方法
  
  // 构造函数
}


// 使用类 实例化对象 基于类 创建对象
const x:类名 = new 类名()

实例属性

通过实例属性(字段)来保存各种类型的数据

class Person {
  name: string = 'jack'
  food?: string
}

const p = new Person()
p.name = 'jack'

console.log(p.name)
console.log('', p.food?.length)

构造函数

实例属性一般都要给一个初始值,但有构造函数就可以再实例化对象时再赋值

class 类{
  字段A:类型
  字段B:类型

  constructor(参数...) {
    // 通过 new 实例化的时候 会调用 constructor
    // 通过关键字 this 可以获取到实例对象
  }
}
const 实例 = new 类()

示例:

interface IFood {
  name: string
  price: number
}

class Food {
  name: string
  price: number

  // constructor(name:string,price:number) {
  //   this.name=name
  //   this.price = price
  // }
  constructor(value: IFood) {
    this.name = value.name
    this.price = value.price
  }
}

// const f = new Food('西兰花炒蛋', 15)
const f = new Food({ name: '花菜炒蛋', price: 10 })

实例方法

类中还可以定义方法

class Person{
  name:string

  constructor(name:string) {
    this.name = name
  }

  sayHi(name:string){
    console.log(`你好${name},我的名字是:${this.name}`)
  }
}

const p:Person = new Person('jack')
p.sayHi('rose')

静态属性、方法

// 定义
class 类{
  static 字段:类型
  static 方法(){}
}

// 使用
类.字段
类.方法()

通过类来调用

继承

可以通过继承来获取父类的属性、方法

class 父类 {
  // 字段
  // 方法
  // 构造函数
}

class 子类 extends 父类{
  // 自己的字段(属性)
  // 自己的方法
  // 可以重写父类方法
}

super关键字

子类通过 super 可以访问父类的实例字段、实例方法和构造函数

class 父类 {
  func(){
    
  }
}

class 子类 extends 父类 {

  constructor() {
    super() // 调用父类构造函数
  }
  方法(){
    super.方法() // 调用父类方法
  }
}

示例

class Person {
  name: string
  age: number

  sayHi() {
    console.log(`你好,我叫:${this.name}`)
  }

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

class Student extends Person {
  height: number

  constructor(name: string, age: number, height: number) {
    // name 和 age 的初始化通过 super 来调用父类的构造函数
    super(name, age)
    this.height = height
  }

  sayHi(): void {
    // 通过 super 访问父类的 字段 方法
    super.sayHi()
    super.name
    super.age
    console.log('子类的 sayHi')
  }
}

const s: Student = new Student('jack', 18, 170)

接口补充

接口继承

interface 接口1{
  属性1:类型
}
interface 接口2 extends 接口1 {
  属性2:类型
}

示例:

interface IFood {
  name: string
}

interface IVegetable extends IFood {
  color: string
}

const flower: IVegetable = {
  name: '西兰花',
  color: '黄绿色'
}

接口实现(通过类来实现)

通过接口来对类作出限制

interface 接口{
  属性:类型
  方法:方法类型
}

classimplements 接口{
  // 必须实现 接口中定义的 属性、方法,否则会报错
}

“本文正在参加华为鸿蒙有奖征文征文活动”