HarmonyOS第二课——TypeScript快速入门

365 阅读7分钟

编程语言介绍

ArkTS是HarmonyOS优选的主力应用开发语言。它在TypeScript(简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。要了解什么是ArkTS,我们首先要了解下ArkTS、TypeScript和JavaScript之间的关系:

  • JavaScript是一种属于网络的高级脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。
  • TypeScript 是 JavaScript 的一个超集,它扩展了 JavaScript 的语法,通过在JavaScript的基础上添加静态类型定义构建而成,是一个开源的编程语言。
  • ArkTS兼容TypeScript语言,拓展了声明式UI、状态管理、并发任务等能力。

由此可知,TypeScript是JavaScript的超集,ArkTS则是TypeScript的超集,他们的关系如下图所示:

image.png

基础类型

TypeScript支持一些基础的数据类型,如布尔型、数组、字符串等,下文举例几个较为常用的数据类型,我们来了解下他们的基本使用。

布尔值

TypeScript中可以使用boolean来表示这个变量是布尔值,可以赋值为true或者false。

let isBool: boolean = false;

数字

TypeScript里的所有数字都是浮点数,这些浮点数的类型是 number。除了支持十进制,还支持二进制、八进制、十六进制。

let number1: number = 10;
let number2: number = 1.4;
let number3: number = 0b11111100111;
let number4: number = 0o3747;
let number5: number = 0x7e7;

字符串

TypeScript里使用 string表示文本数据类型, 可以使用双引号( ")或单引号(')表示字符串。

let str: string = "哈哈";
let str2: string = '你好';

数组

TypeScrip有两种方式可以定义数组。 第一种,可以在元素类型后面接上 [],表示由此类型元素组成的一个数组。

let num: number[] = [1,3,6,7];

第二种方式是使用数组泛型,Array<元素类型>。

let num: Array<number> = [1,3,5];

元组

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组。

let res: [string,number] = ['Hello',10];
console.log(res);
console.log(res[0]);

枚举

enum类型是对JavaScript标准数据类型的一个补充,使用枚举类型可以为一组数值赋予友好的名字。

enum Color {Red, Green, Blue};
let c: Color = Color.Red;

Unknown

有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。那么我们可以使用unknown类型来标记这些变量。

let notSure: unknown = 4;
notSure = '哈哈';
notSure = true;

Void

当一个函数没有返回值时,你通常会见到其返回值类型是 void。

function test(): void {  
 }

Null 和 Undefined

TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。

let u: undefined = undefined;
let n: null = null;

联合类型

联合类型(Union Types)表示取值可以为多种类型中的一种。

let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;

条件语句

条件语句用于基于不同的条件来执行不同的动作。TypeScript 条件语句是通过一条或多条语句的执行结果(True 或 False)来决定执行的代码块。

if...else 语句

var num:number = 2 
if(num > 0) {  
    console.log(num+' 是正数')
} else if(num < 0) {
    console.log(num+' 是负数')
} else {   
    console.log(num+' 为0')
}

switch…case 语句

一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查。

var grade:string = 'A'; 
switch(grade) {    
    case 'A': {      
    console.log('优');   
    break;   
    }  
    case 'B': {       
    console.log('良');       
    break;   
    }    
    case 'C': {     
    console.log('及格');    
    break;    
    }    
    case 'D': {      
    console.log('不及格');   
    break;   
    }     
    default: {      
    console.log('非法输入');   
    break;                
} }

函数

函数是一组一起执行一个任务的语句,函数声明要告诉编译器函数的名称、返回类型和参数。TypeScript可以创建有名字的函数和匿名函数,其创建方法如下

// 有名函数
function sum(x: number,y: number){
return x + y
}
// 调用
console.log(sum(10,29));

//匿名函数
let sum = function(x: number, y: number){
return x + y;
}
sum(20,30);

可选参数

在TypeScript里我们可以在参数名旁使用 ?实现可选参数的功能。 比如,我们想让lastName是可选的:

function myName(firstName:string, lastName?: string){
    if (lastName){
        return firstName + " " + lastName ;
    }
        return firstName;
}
console.log(myName("a","b"));
console.log(myName("a"));

箭头函数

ES6版本的TypeScript提供了一个箭头函数,它是定义匿名函数的简写语法,用于函数表达式,它省略了function关键字。箭头函数的定义如下,其函数是一个语句块:

( [param1, parma2,…param n] )=> { 
// 代码块
}

其中,括号内是函数的入参,可以有0到多个参数,箭头后是函数的代码块。我们可以将这个箭头函数赋值给一个变量,如下所示:

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

如何要主动调用这个箭头函数,可以按如下方法去调用:

sum(10,20);

TypeScript支持基于类的面向对象的编程方式,定义类的关键字为 class,后面紧跟类名。类描述了所创建的对象共同的属性和方法。

类的定义

class Persion{
    private name: string
    private age: number

//构造方法
constructor(name:string, age: number){
    this.name = name
    this.age = age
}

public getPersionInfo(): string{
    return '姓名: ${this.name} age:${this.age}';
    }
}
let p = new Persion('哈哈',15);
console.log(p.getPersionInfo());

继承

继承就是子类继承父类的特征和行为,使得子类具有父类相同的行为。TypeScript中允许使用继承来扩展现有的类,对应的关键字为extends。

class Student extends Persion{
    private score: number
    constructor(name:string ,age: number, score: number){
    super(name,age);
    this.score = score;
    }
}

模块

随着应用越来越大,通常要将代码拆分成多个文件,即所谓的模块(module)。模块可以相互加载,并可以使用特殊的指令 export 和 import 来交换功能,从另一个模块调用一个模块的函数。

两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。

导出

任何声明(比如变量,函数,类,类型别名或接口)都能够通过添加export关键字来导出,例如我们要把Persion这个类导出,代码示意如下

export class Persion{
    name: string
    age: number
    constructor(name: string ,age: number){
    this.name = name;
    this.age = age;
    }
}

导入

模块的导入操作与导出一样简单。 可以使用以下 import形式之一来导入其它模块中的导出内容。

import{Persion} from '../common/Persion';

迭代器

当一个对象实现了Symbol.iterator属性时,我们认为它是可迭代的。一些内置的类型如Array,Map,Set,String,Int32Array,Uint32Array等都具有可迭代性。

for..of 语句

for..of会遍历可迭代的对象,调用对象上的Symbol.iterator方法。 下面是在数组上使用for..of的简单例子

let array = [3,5,6,8];
for( let value of array){
    console.log(value); // 3 5 6 8
}

for..of vs. for..in 语句

for..of和for..in均可迭代一个列表,但是用于迭代的值却不同:for..in迭代的是对象的键,而for..of则迭代的是对象的值。

let array = [3,5,6,8];
for( let value of array){
    console.log(value); // 3 5 6 8
}

for(let index in array){
    console.log(index); // 0 1 2 3
}

如果没有搭建TypeScript的开发环境,也可以直接使用在线Playground平台www.typescriptlang.org/play)进行编码练习