【HarmonyOS】HarmonyOS NEXT学习日记:二、ArkTs语法

【HarmonyOS】HarmonyOS NEXT学习日记:二、ArkTs语法

众所周知TS是JS的超集,而ArkTs则可以理解为是Ts的超集。他们的基础都基于JS,所以学习之前最好就JS基础。我的学习重点也是放在ArkTs和JS的不同点上。

文章主要跟着官方文档学习,跳过了一些和js相同的地方,保留了一些js和ts不同的地方,同时在一些概念上添加了额外的解读和代码注释。方便ts基础不太扎实或者还没接触过的同学阅读。

在这里插入图片描述

声明

声明变量关键字和js一样,let、const

ArkTS是一种静态类型语言,所有数据的类型都必须在编译时确定,但是定义时有初始值则可以显式指定其类型。

let str: string = 'hello';
let str2= 'hello, world';

上面两种都是定义了string类型的变量。

类型

基本类型和js差不多,主要看看声明类型,和一些特殊的类型用法

String

字符串

let str: string = 'hello';
let str2:string= `The result is ${a}`;

Number

数字

let num: number= 1;

Boolean

布尔类型

let flag: boolean = false;

Void

void类型用于指定函数没有返回值。可以用于泛型类型参数。泛型是什么我们后面会提到。

Object

所有引用类型的基类型

Array

let values: number[] = [1, 2, 3];

Enum

枚举值

enum ColorSet { Red, Green, Blue }
let c: ColorSet = ColorSet.Green;
console.log(c)//2
enum ColorSet { White = '0xFF', Grey = '0x7F', Black = '0x00' }
let c: ColorSet = ColorSet.Black;
console.log(c)//0x00

Union类型

联合类型,是由多个类型组合成的引用类型。联合类型包含了变量可能的所有类型。
比如我想要一个数组既可以储存string也可以储存number就可以像下面这样:

type x = string | number;
let arr: x[] = [1, '2'];

用type定义一个名为x的联合类型,然后使用他声明arr的类型即可。

Aliases

Aliases类型为匿名类型(数组、函数、对象字面量或联合类型)提供名称,或为已有类型提供替代名称。

比如我希望把两层的数组类型多处复用,给这种类型命名Matrix,则可以像下面这样

type Matrix = (number|string)[][]
let arr:Matrix = [[1,2,3],['4','5','6']]

运算符

和js基本一致,略过。想要详细了解的同学可以查看官方文档

语句

什么if else switch之类的用法和js一致,略过。想要详细了解的同学可以查看官方文档

函数

函数声明

函数声明引入一个函数,包含其名称、参数列表、返回类型和函数体。

以下示例是一个简单的函数,包含两个string类型的参数,返回类型为string:

function add(x: string, y: string): string {let z: string = `${x} ${y}`;return z;
}

可选参数

可选参数的格式可为name?: Type

function hello(name?: string) {if (name == undefined) {console.log('undefined');} else {console.log(name);}
}

当然也可以设置参数缺省值

function hello(name: string = 'me') {console.log(name);
}
hello()//输出me

Rest参数

用法与js相同
Rest就是为解决传入的参数数量不一定, rest parameter(Rest 参数) 本身就是数组,数组的相关的方法都可以用。
函数的最后一个参数可以是rest参数。

function sum(...numbers: number[]): number {let res = 0;for (let n of numbers)res += n;return res;
}sum() // 返回0
sum(1, 2, 3) // 返回6

返回类型

如果可以从函数体内推断出函数返回类型,则可在函数声明中省略标注返回类型。

// 显式指定返回类型
function foo(): string { return 'foo'; }// 推断返回类型为string
function goo() { return 'goo'; }

不需要返回值的函数的返回类型可以显式指定为void或省略标注。这类函数不需要返回语句。

function hi1() { console.log('hi'); }
function hi2(): void { console.log('hi'); }

以上两种均可。

函数类型

函数类型通常用于定义回调

type trigFunc = (x: number) => number // 这是一个函数类型function do_action(f: trigFunc) {f(3.141592653589); // 调用函数
}do_action(Math.sin); // 将函数作为参数传入

箭头函数

let sum = (x: number, y: number): number => {return x + y;
}

返回类型可以省略;省略时,返回类型通过函数体推断

函数重载

function foo(x: number): void;            /* 第一个函数定义 */
function foo(x: string): void;            /* 第二个函数定义 */
function foo(x: number | string): void {  /* 函数实现 */
}foo(123);     //  OK,使用第一个定义
foo('aa'); // OK,使用第二个定义

通过 class 关键字来定义一个类, 使用 constructor 定义构造函数。

class Person {name: string = ''surname: string = ''constructor (n: string, sn: string) {this.name = n;this.surname = sn;}fullName(): string {return this.name + ' ' + this.surname;}
}

定义类后,可以使用关键字new创建实例

let p = new Person('John', 'Smith');
console.log(p.fullName());

或者,可以使用对象字面量创建实例:

class Point {x: number = 0y: number = 0
}
let p: Point = {x: 42, y: 42};

字段

字段是直接在类中声明的某种类型的变量。

类可以具有实例字段或者静态字段。

使用关键字static将字段声明为静态。静态字段属于类本身,类的所有实例共享一个静态字段。

ArkTS要求所有字段在声明时或者构造函数中显式初始化.

class Person {static numberOfPersons = 0constructor() {Person.numberOfPersons++;}
}
let me = new Person()
let you = new Person()
console.log(Person.numberOfPersons+'' )//2

getter和setter

setter和getter可用于提供对对象属性的受控访问。

class Person {name: string = ''private _age: number = 0get age(): number { return this._age; }set age(x: number) {if (x < 0) {throw Error('Invalid age argument');}this._age = x;}
}let p = new Person();
p.age; // 输出0
p.age = -42; // 设置无效age值会抛出错误

方法

方法属于类。类可以定义实例方法或者静态方法。静态方法属于类本身,只能访问静态字段。而实例方法既可以访问静态字段,也可以访问实例字段,包括类的私有字段。

!!!所谓的静态方法和静态字段,都属于这个类,而非实例。所以实例是无法调用的,要调用只能通过这个类来调用。!!!

构造函数

类声明可以包含构造函数,使用constructor声明,所谓构造函数就是用来初始化对象状态的
如果未定义构造函数,则会自动创建具有空参数列表的默认构造函数

构造函数重载签名

可以通过编写重载签名,指定构造函数的不同调用方式。具体方法为,为同一个构造函数写入多个同名但签名不同的构造函数头,构造函数实现紧随其后。

class C {constructor(x: number)             /* 第一个签名 */constructor(x: string)             /* 第二个签名 */constructor(x: number | string) {  /* 实现签名 */}
}
let c1 = new C(123);      // OK,使用第一个签名
let c2 = new C('abc');    // OK,使用第二个签名

继承

使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法。

  • 子类继承父类后子类的实例就拥有了父类中的属性和方法,但不继承构造函数
  • 子类自己特殊逻辑放在子类中重写父类的逻辑
  • super 可以调用父类上的方法和属性
class Person {name: string = ''private _age = 0get age(): number {return this._age;}
}
class Employee extends Person {salary: number = 0calculateTaxes(): number {return this.salary * 0.42;}
}

也可以用implements实现对接口的继承,但是包含implements子句的类必须实现列出的接口中定义的所有方法,但使用默认实现定义的方法除外。

interface DateInterface {now(): string;
}
class MyDate implements DateInterface {now(): string {// 在此实现return 'now is now';}
}

父类访问

关键字super可用于访问父类的实例字段、实例方法和构造函数。在实现子类功能时,可以通过该关键字从父类中获取所需接口。

我们刚刚说过继承来的子类无法继承构造函数,如果要用的话就可以通过super实现

class RectangleSize {protected height: number = 0protected width: number = 0constructor (h: number, w: number) {this.height = h;this.width = w;}draw() {/* 绘制边界 */}
}
class FilledRectangle extends RectangleSize {color = ''constructor (h: number, w: number, c: string) {super(h, w); // 父类构造函数的调用this.color = c;}draw() {super.draw(); // 父类方法的调用// super.height -可在此处使用/* 填充矩形 */}
}

方法重写

子类可以重写其父类中定义的方法的实现。重写的方法必须具有与原始方法相同的参数类型和相同或派生的返回类型。

方法重载签名

通过重载签名,指定方法的不同调用。具体方法为,为同一个方法写入多个同名但签名不同的方法头,方法实现紧随其后

class C {foo(x: number): void;            /* 第一个签名 */foo(x: string): void;            /* 第二个签名 */foo(x: number | string): void {  /* 实现签名 */}
}
let c = new C();
c.foo(123);     // OK,使用第一个签名
c.foo('aa'); // OK,使用第二个签名

可见性修饰符

类的方法和属性都可以使用可见性修饰符。
可见性修饰符包括:private、protected和public。默认可见性为public。

  • public 自己、自己的子类 和其他类都可以访问 (默认值)
  • protected 受保护的 自己和自己的子类能访问, 其他类不能访问
  • private 私有的 只能自己访问,自己的子类不能访问,其他类更不能访问
Private
class C {public x: string = ''private y: string = ''set_y (new_y: string) {this.y = new_y; // OK,因为y在类本身中可以访问}
}
let c = new C();
c.x = 'a'; // OK,该字段是公有的
c.y = 'b'; // 编译时错误:'y'不可见
Protected
class Base {protected x: string = ''private y: string = ''
}
class Derived extends Base {foo() {this.x = 'a'; // OK,访问受保护成员this.y = 'b'; // 编译时错误,'y'不可见,因为它是私有的}
}

对象字面量

对象字面量是一个表达式,可用于创建类实例并提供一些初始值。它在某些情况下更方便,可以用来代替new表达式。

class C {n: number = 0s: string = ''
}let c: C = {n: 42, s: 'foo'};

对象字面量只能在可以推导出该字面量类型的上下文中使用

Record类型的对象字面量

泛型Record<K, V>用于将类型(键类型)的属性映射到另一个类型(值类型)。常用对象字面量来初始化该类型的值

let map: Record<string, number> = {'John': 25,'Mary': 21,
}map['John']; // 25

类型K可以是字符串类型或数值类型,而V可以是任何类型.

interface PersonInfo {age: numbersalary: number
}
let map: Record<string, PersonInfo> = {'John': { age: 25, salary: 10},'Mary': { age: 21, salary: 20}
}

接口

接口声明引入新类型。接口是定义代码协定的常见方式。

任何一个类的实例只要实现了特定接口,就可以通过该接口实现多态。
所谓多态,就是一个类只能继承一个父类,但是可以继承多个接口从而实现多态。

接口使用interface关键字声明

interface Style {color: string // 属性
}
interface AreaSize {calculateAreaSize(): number // 方法的声明someMethod(): void;     // 方法的声明
}

类继承接口使用implements

// 接口:
interface AreaSize {calculateAreaSize(): number // 方法的声明someMethod(): void;     // 方法的声明
}// 实现:
class RectangleSize implements AreaSize {private width: number = 0private height: number = 0someMethod(): void {console.log('someMethod called');}calculateAreaSize(): number {this.someMethod(); // 调用另一个方法并返回结果return this.width * this.height;}
}

接口继承

接口也可以使用extends 实现继承

interface Style {color: string
}interface ExtendedStyle extends Style {width: number
}

泛型类型和函数

泛型类型和函数允许创建的代码在各种类型上运行,而不仅支持单一类型。
即将数据类型也作为参数传递

class CustomStack<Element> {//这里定义了一个Element形参,作为类型public push(e: Element):void {//内部的push方法接受的参数使用Element为类型// ...}
}
let s = new CustomStack<string>();//在实例化的时候,传入Element的实参string用来当做push方法的入参类型
s.push('hello');

泛型约束

泛型类型的类型参数可以被限制只能取某些特定的值。例如,MyHashMap<Key, Value>这个类中的Key类型参数必须具有hash方法。

interface Hashable {hash(): number
}
class MyHashMap<Key extends Hashable, Value> {public set(k: Key, v: Value) {let h = k.hash();// ...其他代码...}
}

泛型函数

使用泛型函数可编写更通用的代码。比如返回数组最后一个元素的函数:

function last(x: number[]): number {return x[x.length - 1];
}
last([1, 2, 3]); // 3

以上方法只能用于number数组,
如果需要为任何数组定义相同的函数,使用类型参数将该函数定义为泛型:

function last<T>(x: T[]): T {return x[x.length - 1];
}

现在,该函数可以与任何数组一起使用。

// 显式设置的类型实参
last<string>(['aa', 'bb']);
last<number>([1, 2, 3]);// 隐式设置的类型实参
// 编译器根据调用参数的类型来确定类型实参
last([1, 2, 3]);

泛型默认值

泛型类型的类型参数可以设置默认值。这样可以不指定实际的类型实参,而只使用泛型类型名称。下面的示例展示了类和函数的这一点。

class SomeType {}
interface Interface <T1 = SomeType> { }
class Base <T2 = SomeType> { }
class Derived1 extends Base implements Interface { }
// Derived1在语义上等价于Derived2
class Derived2 extends Base<SomeType> implements Interface<SomeType> { }function foo<T = number>(): T {// ...
}
foo();
// 此函数在语义上等价于下面的调用
foo<number>();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/47077.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

框架设计MVC

重点&#xff1a; 1.用户通过界面操作&#xff0c;传输到control&#xff0c;control可以直接去处理View&#xff0c;或者通过模型处理业务逻辑&#xff0c;然后将数据传输给view。 2.control包含了model和view成员。 链接&#xff1a; MVC框架详解_mvc架构-CSDN博客 MVC架…

【Docker】Docker 的数据管理与镜像创建

目录 一.数据管理 1.数据卷 2.数据卷容器 二.端口映射 三.容器互联 四.Docker 镜像的创建 1.基于现有镜像创建 1.1.首先启动一个镜像&#xff0c;基于镜像创建容器&#xff0c;更新容器内容 1.2.将修改后的容器提交为新的镜像&#xff0c;需要使用该容器的 ID 号创建新…

算法2--贪心算法

1.老鼠和猫的交易 小老鼠准备了M磅的猫粮&#xff0c;准备去和看守仓库的猫做交易&#xff0c;因为仓库里有小老鼠喜欢吃的五香豆。 仓库有N个房间&#xff1b; 第i个房间有 J[i] 磅的五香豆&#xff0c;并且需要用 F[i] 磅的猫粮去交换&#xff1b; 老鼠不必交换该房间所有的五…

中国星坤X0800HI系列线对板连接器:创新技术连接,引领智能家居未来!

近日&#xff0c;中国星坤推出的X0800HI系列线对板连接器&#xff0c;凭借其独特的设计和卓越的性能&#xff0c;引起了业界的广泛关注。 X0800HI系列线对板连接器在极小空间内实现了线对板的W-B连接&#xff0c;这不仅解决了传统连接方式中剥线和焊接的繁琐步骤&#xff0c;还…

django踩坑(四):终端输入脚本可正常执行,而加入crontab中无任何输出

使用crontab执行python脚本时&#xff0c;有时会遇到脚本无法执行的问题。这是因为crontab在执行任务时使用的环境变量与我们在终端中使用的环境变量不同。具体来说&#xff0c;crontab使用的环境变量是非交互式(non-interactive)环境变量&#xff0c;而终端则使用交互式(inter…

Hyper-V和VMWare使用对比

图片来自互联网 1.起因 最近在学习Linux相关的知识&#xff0c;第一步当然就是装虚拟机了。之前是基于微软Hyper-V平台装的Ubuntu,用起来总是感觉卡卡的。我还一直天真的以为虚拟机都是这个样子的&#xff0c;直到用了VMWare之后…。VMWare我主要装的是VMWare16Pro&#xff0…

224 |《乡下人的悲歌》也是城市中产的呜咽

今天《乡下人的悲歌》和他的作者火了&#xff1a;詹姆斯戴维万斯&#xff08;James David Vance&#xff09;被共和党提名为副总统候选人。 以下是最能代表这本书的一个重要观点&#xff1a; I dont believe in epiphanies. I dont believe in transformativemoments, as trans…

C++:链表插入排序/删除重复节点题解

插入排序 插入排序的思路很简单&#xff0c;基本都知道。 关键是放在链表中&#xff0c; 1.要建立一个哨兵位&#xff0c;这个哨兵位的下一个节点&#xff0c;始终指向val最小的节点。 2.prev指针作为cur的前一个节点&#xff0c;始终指向val最大的节点。它的下一个节点始终…

JavaFX+MySQL实现图书管理系统(包含完整代码)

目录 一、功能介绍 1.ER图 2.学生管理员登陆页面 3.图书馆首页 4.学生图书馆搜索界面 5.学生注册 6.管理员后台 增加书籍 查看借阅记录 ​编辑 修改图书 二、功能分解 1.界面展示 2.点击按钮切换页面 普通按钮点击 复杂按钮点击 3.登录注册 创建登陆注册的页…

逆向学习思路链接分享

学好逆向先学C 然后我们需要学习好 编码问题CTF常见编码及加解密&#xff08;超全&#xff09; - ruoli-s - 博客园 (cnblogs.com) 并且规划好学习路线 CTF逆向Reverse入门学习路线&#xff08;面向小白&#xff09;_逆向reverse 思路-CSDN博客 并且安好反编译的环境 x64d…

【教学类-67-02】20240716毛毛虫ABB排序

背景需求&#xff1a; 【教学类-67-01】20240715毛毛虫AB排序-CSDN博客文章浏览阅读584次&#xff0c;点赞16次&#xff0c;收藏6次。【教学类-67-01】20240715毛毛虫AB排序https://blog.csdn.net/reasonsummer/article/details/140443310 在AB排序基础上&#xff0c;继续制作…

【Django+Vue3 线上教育平台项目实战】登录功能模块之短信登录与钉钉三方登录

文章目录 前言一、几个关键概念1.HTTP无状态性2.Session机制3.Token认证4.JWT 二、通过手机号验证码登录1.前端短信登录界面2.发送短信接口与短信登录接口3.Vue 设置interceptors拦截器4. 服务端验证采用自定义中间件方式实现5. 操作流程及效果图如下&#xff1a; 三、通过第三…

记录些MySQL题集(9)

MySQL之死锁问题分析、事务隔离与锁机制的底层原理剖析 一、MySQL中的死锁现象 所谓的并发事务&#xff0c;本质上就是MySQL内部多条工作线程并行执行的情况&#xff0c;也正由于MySQL是多线程应用&#xff0c;所以需要具备完善的锁机制来避免线程不安全问题的问题产生&#…

手机如何伪装ip网络地址

伪装IP地址是指通过技术手段修改网络设备的IP地址&#xff0c;使其看起来像是来自另一个网络位置。这种技术通常用于隐藏真实的网络活动&#xff0c;以保护隐私。那么&#xff0c;手机如何伪装IP网络地址&#xff1f; 要在手机上伪装IP地址&#xff0c;‌可以通过下载和安装手机…

数据资产通证化,堪比20年前的房地产?

大数据产业创新服务媒体 ——聚焦数据 改变商业 想象一下&#xff0c;一个简单的点击&#xff0c;一次不经意的搜索&#xff0c;一段简短的对话&#xff0c;它们在数字世界里留下了什么&#xff1f;是的&#xff0c;是数据。这些看似微不足道的数字碎片&#xff0c;汇聚成海&a…

【python】PyQt5的窗口界面的各种交互逻辑实现,轻松掌控图形化界面程序

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【中项】系统集成项目管理工程师-第一模块:IT技术和管理-1.1信息与信息化-1.1.2信息系统基础

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&#xff0c;目前涵盖了计算机软件、计算机网络、计算机应…

Office动态水印终于来了

在信息安全日益重要的今天&#xff0c;保护敏感信息变得尤为关键。目前&#xff0c;动态水印甚至是盲水印技术已经在各种企业软件中广泛应用&#xff0c;常见的钉钉和企业微信等都已经支持此类技术&#xff0c;用户查看消息时画面会显示对应用户的姓名和工号等&#xff0c;而作…

小程序-视图与逻辑

一、页面导航 声明式导航 编程式导航 导航传参 1.声明式导航传参 2.编程式导航传参 3.在onload中接收导航参数 二、页面事件 下拉刷新 上拉触底 三、生命周期 分类 生命周期函数分类 1.应用的生命周期函数 2.页面的生命周期函数 四、WXS脚本 基础语法 wxs的特点 五、案…

几何相关计算

目录 一、 判断两个矩形是否相交 二、判断两条线段是否相交 三、判断点是否在多边形内 四、垂足计算 五、贝塞尔曲线 六、坐标系 一、 判断两个矩形是否相交 当矩形1的最大值比矩形2的最小值都小&#xff0c;那矩形1和矩形2一定不相交&#xff0c;其他同理。 struct Po…