一. 什么是arkts
ArkTS是HarmonyOS优选的主力应用开发语言。
ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,保持了TS的基本风格,同时通过规范定义强化开发期静态检查和分析,提升程序执行稳定性和性能。TypeS
cript深受开发者的喜爱,因为它提供了一种更结构化的JavaScript编码方法。
ArkTS旨在保持TypeScript的大部分语法,为现有的TypeScript开发者实现无缝过渡,让移动开发者快速上手ArkTS。
二. arkts想比TS特性差异
ArkTS通过规范约束了TS中过于灵活而影响开发正确性或者给运行时带来不必要额外开销的特性,下面通过代码片段说明部分约束特性。
三. arkts基本知识
1.声明
arkts通过声明引入变量、常量、函数和类型
(1)变量声明
变量声明以关键字let开头的声明引入变量,该变量在程序执行期间可以具有不同的值。
javascript
// 声明了字符串变量
let str:string='hello'
//修改str变量的值为hello word
str='hello word'
(2)常量声明
常量以关键字 const 开头的声明引入只读常量,该常量只能被赋值一次。
对常量重新赋值会造成编译时错误
javascript
const str1:string='hello'
2.自动类型推断
由于arkts是一种静态类型语言,所有数据的类型都必须在编译时确定。
但是,如果一个变量或常量的声明包含了初始值,那么开发者就不需要显式指定其类型。ArkTS规范中列举了所有允许自动推断类型的场景。
javascript
// 不省略数据类型声明
let str:string='hello';
// 自动类型推断
let str1='hello word'
//出现错误示范
// str1=123 // 上面声明为字符串类型,而重新赋值为数字类型则报错
// let str // 未给初始值则报错
3.arkts中的类型
(1)number类型
ArkTS提供number和Number类型,任何整数和浮点数都可以被赋给此类型的变量。 数字字面量包括整数字面量和十进制浮点数字面量。
整数字面量包括以下类别: 由数字序列组成的十进制整数。例如:0、117、-345
javascript
// 十进制
let num1:number=123
以0x(或0X)开头的十六进制整数,可以包含数字(0-9)和字母a-f或A-F。例如:0x1123、0x00111、-0xF1A7
javascript
let num4:number=0xfac; // 十六进制
以0o(或0O)开头的八进制整数 ,只能包含数字(0-7)。例如:0o777
javascript
let num3:number=0o17161; // 八进制
以0b(或0B)开头的二进制整数,只能包含数字0和1。例如:0b11、0b0011、-0b11
javascript
let num2:number=0b10101; // 二进制
浮点字面量包括以下:十进制整数,可为有符号数(即,前缀为"+"或"-"); 小数点(".")
javascript
// 浮点字面量
let num1:number=+1;
let num2:number=-1;
let num3:number=1.1;
小数部分(由十进制数字字符串表示) 以"e"或"E"开头的指数部分,后跟有符号(即,前缀为"+"或"-")或无符号整数。
(2)boolean类型
boolean类型由true和false两个逻辑值组成。
javascript
console.log(3>2) //返回结果为true
console.log(5<4) //返回结果为false
(3)string类型
string代表字符序列;可以使用转义字符来表示字符。
字符串字面量由单引号(')或双引号(")之间括起来的零个或多个字符组成。
字符串字面量还有一特殊形式,是用反向单引号(``)括起来的模板字面量。
javascript
// 单引号
let str5:string='hello word';
// 双引号
let str6:string="hello word";
// 反引号
let str7:string=`hello word ${num1}`;
//转义
let str8:string='hello word\n';
(4)null类型
javascript
let a:null=null
(5)undefined类型
javascript
let b:undefined=undefined
// 或者
let b1:string;
(6)void类型
void类型用于指定函数没有返回值。 此类型只有一个值,同样是void。由于void是引用类型,因此它可以用于泛型类型参数。
javascript
function abc2():void{
// void:没有返回值,不能有返回值
}
(7)Object类型
Object类型是所有引用类型的基类型。任何值,包括基本类型的值(它们会被自动装箱),都可以直接被赋给Object类型的变量。
javascript
let ob:Object=123;
(8)array类型
**array,即数组,是由可赋值给数组声明中指定的元素类型的数据组成的对象。 数组可由数组复合字面量(即用方括号括起来的零个或多个表达式的列表,其中每个表达式为数组中的一个元素)来赋值。数组的长度由数组中元素的个数来确定。**数组中第一个元素的索引为0。
TypeScript
let arr:number[]=[1,2,3,4,5,6]
(9)enum类型
enum类型,又称枚举类型,是预先定义的一组命名值的值类型,其中命名值又称为枚举常量。
TypeScript
enum sex{
男,女
}
使用枚举常量时必须以枚举类型名称为前缀
TypeScript
let str:Sex=Sex.男
// 也可以用数字表示
let sex2:Sex=1;
(10)union类型
union类型,即联合类型,是由多个类型组合成的引用类型。联合类型包含了变量可能的所有类型。
TypeScript
class Dog{
play(){
console.log('狗')
}
}
export class Cat{
play(){
console.log('猫')
}
}
class Penguin{
play(){
console.log('企鹅')
}
}
// Pet 是联合类型
type Pet=Dog|Cat|Penguin
let p1:Pet=new Dog();
p1.play()
(11)Aliases类型
Aliases类型为匿名类型(数组、函数、对象字面量或联合类型)提供名称,或为已有类型提供替代名称。
TypeScript
type fun=(a:string)=>string
4.运算符
(1)赋值运算符
赋值运算符=,使用方式如x=y。
javascript
let a:number=1
(2)算术运算符
(3)比较运算符
(4)一元运算符
++:自增 -- :自减
(5)逻辑运算符
(6)位运算符
& 可以用来判断奇偶数
TypeScript
let flag = (12 & 1) == 0
console.log(`${flag}`)
(7)复合赋值运算符
复合赋值运算符列举如下:+=、-=、*=、/=、%=、<<=、>>=、>>>=、&=、|=、^=。
5.语句
(1)if语句
if语句用于需要根据逻辑条件执行不同语句的场景。当逻辑条件为真时,执行对应的一组语句,否则执行另一组语句(如果有的话)。
else部分也可能包含if语句。 条件表达式可以是任何类型。但是对于boolean以外的类型,会进行隐式类型转换:
TypeScript
// 如果3>2为真就执行第一条语句,否则执行语句2
if(3>2){
// 语句1
console.log('true')
}else{
// 语句2
console.log('false')
}
(2)switch语句
使用switch语句来执行与switch表达式值匹配的代码块。
如果switch表达式的值等于某个label的值,则执行相应的语句。
如果没有任何一个label值与表达式值相匹配,并且switch具有default子句,那么程序会执行default子句对应的代码块。
break语句(可选的)允许跳出switch语句并继续执行switch语句之后的语句。 如果没有break语句,则执行switch中的下一个label对应的代码块。
TypeScript
let a:number=3;
switch(a){
case 1:
console.log('第一名')
break
case 2:
console.log('第二名')
break
case 3:
console.log('第三名')
break
default:
console.log('没有获得名次')
};
(3)三元表达式
条件表达式由第一个表达式的布尔值来决定返回其它两个表达式中的哪一个
TypeScript
console.log(a>b?'a大于b':'a小于b');
判断a>b,如果a>b 执行第一条语句,否则执行第二条语句
(4)for循环语句
for语句会被重复执行,直到循环退出语句值为false。
for语句的执行流程如下:
1、 执行init表达式(如有)。此表达式通常初始化一个或多个循环计数器。
2、 计算condition。如果它为真值(转换后为true的值),则执行循环主体的语句。如果它为假值(转换后为false的值),则for循环终止。
3、 执行循环主体的语句。
4、 如果有update表达式,则执行该表达式。
5、 回到步骤2。
TypeScript
let sum:number=0
for(let i=0;;i<=10;i++){
sum += i
}
console.log(i)
(5)for-of语句
使用for-of语句可遍历数组或字符串
TypeScript
let arr:number[]=[1,2,3,4,5,6]
for (let i of arr){
console.log(`${i}`)
}
// 遍历字符串
let str:string='hello'
for (let a of str){
console.log(a)
}
(6)while语句
只要condition为真值(转换后为true的值),while语句就会执行statements语句
TypeScript
let a:number=0
while(a<=10){
console.log(`${a}`)
a++
}
(7)do-while语句
如果condition的值为真值(转换后为true的值),那么statements语句会重复执行
TypeScript
let b=0
do{
console.log(`${{b}`)
b++
}while(b<=10)
(8)break语句
使用break语句可以终止循环语句或switch。
如果break语句后带有标识符,则将控制流转移到该标识符所包含的语句块之外。
TypeScript
let a:number[]=[1,2,3,4,5,6]
// 当i等于3终止循环
for(let i=0;i<a;i++){
if(i==3){
break
}
console.log(i)
}
(9)continue语句
continue语句会停止当前循环迭代的执行,并将控制传递给下一个迭代。
TypeScript
let a:number[]=[1,2,3,4,5,6]
// 当i等于3时跳过本次循环
for(let i=0;i<a;i++){
if(i==3){
continue
}
console.log(i)
}
(10)thorw和try语句
throw语句用于抛出异常或错误:
TypeScript
class Err{
static add(a:number,b:number):number{
if(!b){
//抛出异常
throw new Error('除数不能为0')
}
return a/b
}
}
Err.add(1,0)
try语句用于捕获和处理异常或错误:
TypeScript
function tryCatch(){
let aaa:number=0
try { //有可能出现问题的代码
aaa=Err.add(1,0)
}catch (e){ //出现问题后的解决办法 e---->错误信息
console.log(e)
}
finally 异常的最终处理方案
TypeScript
function tryCatch(){
let aaa:number=0
try { //有可能出现问题的代码
aaa=Err.add(1,0)
}catch (e){ //出现问题后的解决办法 e---->错误信息
console.log(e)
} finally { //异常的最终处理方案
// 不管代码有没有出现异常都会执行
return aaa;
}
6.函数
函数声明引入一个函数,包含其名称、参数列表、返回类型和函数体。
TypeScript
function abc(){
//无参函数,并且没有返回值
}
function abc1():string{
// 除了 void和any,必须有返回值
return 'a'
}
function abc2():void{
// void:没有返回值,不能有返回值
}
(1)可选参数
TypeScript
function getAge(sex:string ,name?:string) {
if(name){
return `${name}${sex}`
}
return `无名${sex}`
}
可选参数的另一种形式为设置的参数默认值。如果在函数调用中这个参数被省略了,则会使用此参数的默认值作为实参。
TypeScript
function a(x:number,y:number=2):number{
return x*y
}
a(1,5) //返回1*5
a(2) //返回 2*2
(2)rest参数
函数的最后一个参数可以是rest参数。使用rest参数时,允许函数或方法接受任意数量的实参。
TypeScript
function ages(name:string,...ages:number[]){
console.log(`${name}班有${ages}.length`)
let sum=0;
for (let el of ages) {
sum+=el
}
console.log(`年龄总和:${sum},平均值${sum/ages.length}`)
return sum/ages.length
}
let avgage=ages('鸿蒙',12,23,18,21,17,19)
(3)返回类型
如果可以从函数体内推断出函数返回类型,则可在函数声明中省略标注返回类型
TypeScript
function abc1():string{
return 'a'
}
// 自动推导函数返回类型
function abc(){
return 'a'
}
不需要返回值的函数的返回类型可以显式指定为void或省略标注。这类函数不需要返回语句
TypeScript
function abc2():void{
console.log('a')
}
(4)函数的作用域
函数中定义的变量和其他实例仅可以在函数内部访问,不能从外部访问。 如果函数中定义的变量与外部作用域中已有实例同名,则函数内的局部变量定义将覆盖外部定义。
(5)函数的调用
调用函数以执行其函数体,实参值会赋值给函数的形参。
TypeScript
function add(a:number,b:number=3){
return a+b;
}
let a1 = add(2,6);
console.log(a1)
let a22 = add(2);
console.log(a22)
(6)函数类型
函数类型通常用于定义回调:
TypeScript
type fc=(str:string)=>string //对字符串进行处理并返回
function syfc(f:fc){
return f('火锅')
}
function cl(str:string){
return str+'丸子'
}
let str33=syfc(cl)
(7)箭头函数(又名lambda函数)
函数可以定义为箭头函数
箭头函数的返回类型可以省略;省略时,返回类型通过函数体推断。
表达式可以指定为箭头函数,使表达更简短
TypeScript
let lam1=(x:number,y:number)=>{return x+y}
lam1(1,2)
let lam2=(x:number,y:number)=>{x+y}
let lam3=(x:number,y:number)=>x+y
//{}省略,必须只有一行代码,不能写return关键字
//()无法省略
let lam4=(x:number,y:number)=>{
x+=10
return x+y
}
(8)闭包
闭包是由函数及声明该函数的环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。
TypeScript
function abc5():()=>number{
let a=0;
let g=():number=>{return a++}
return g
}
let abc6=abc5()
abc6()