输出语句
写法: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)
③ 严格区分大小写
内存中的堆栈空间
说到了数据的存储,那么常量和变量存储在哪里呢
首先我们来了解堆和栈
他们都是内存中存储数据的空间
- 栈:访问速度快,基本数据类型存储在里面
- 堆:存储容量大,引用数据类型存储在里面
再深入了解存储原理
基本数据类型的存储:
直接存储在栈空间中
引用数据类型:
- 栈:存放内存地址(变量在堆中的地址)
- 堆:存放变量的值
处理数据
字符串拼接
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)
}
}
}
注意:
- 状态变量必须设置类型
- 状态变量必须设置初始值
数组
数组是一个容器,可以存储多个数据
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 (表达式) {
case 值1:
与值1匹配执行的语句
break
case 值2:
与值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提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用if、else和else if渲染对应状态下的UI内容。
if、else 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时循环停止,那如果他的值不变呢,循环就不会停止。那一个合格的循环语句该怎么写呢
循环三要素
- 初始值(变量)
- 循环条件
- 变化量(变量计数,自增或自减)
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 接口{
属性:类型
方法:方法类型
}
class 类 implements 接口{
// 必须实现 接口中定义的 属性、方法,否则会报错
}
“本文正在参加华为鸿蒙有奖征文征文活动”