鸿蒙系统ArkTs的ts语法入门
- 前言
- 1. 变量声明
- 2. 数据类型
- 2.1 基本数据类型
- 2.2 复杂数据类型
- 2.3 联合类型
- 2.4 空类型和未定义类型
- 3. 函数
- 3.1 匿名函数和箭头函数
- 4. 类和接口
- 类的访问权限
- 接口
- 类的继承
- 内部类
- 7. 结构体
- 参考材料
前言
-
每个语言都有控制流语句就不写测试代码了。
-
arkTs绝大部分语法继承自ts,然后有些许的语法特性变化,这部分我也会在入门的时候一并记上。用一个图简单说明ArkTs和Ts的关系他就大概这样,两者的大部分语法都是相通的。
-
我之前学过java,所以这不是零基础,至少需要会一种编程语言。
代码自测方式:
5. 新建一个鸿蒙App项目,然后开一个设置按钮进行测试
6. 没有条件的话,https://www.runoob.com/try/runcode.php?filename=ts-hw&type=typescript可以在线测试编程代码。
1. 变量声明
- var:传统声明方式,作用域在函数内部,不过arkTs不让使用var方式,所以我们一般都用let
- let:块级声明方式,作用域在代码块内部
- const:常量,声明之后不可以修改
类型 | 作用域 | 定义后能否修改 | arkts支持 |
var | 方法/类内部 | 是 | 否 |
let | 代码块内部 | 是 | 是 |
const | 代码块内部 | 否 | 是 |
function a() {
{
let a: number = 10
console.log(a + "") // 正常输出
}
//console.log(a) // 报错,超过了作用域
{
var b: number = 10 // arkTs时会编译报错,ts无影响
console.log(b + "") // 正常输出
}
console.log(b + "") // 正常输出
{
const c: number = 10
//c = 20 // 报错,常量不能被修改
console.log(c + "")
}
//console.log(c + "") // 报错,访问不到c
}
a()
//console.log(b + ""); // 报错,访问不到b
2. 数据类型
2.1 基本数据类型
类型 | 名称 | 说明 | arkts支持 |
any | 任意类型 | 不用管他,arkTs不支持该类型 | 否 |
number | 数字类型 | 就是双精度类型,也就是java的double ts语言没有整型,只有这个数字类型 | 是 |
string | 字符串类型 | typeScript的字符串用单引号和双引号都可以,没有强制要求 可以用反引号使用表达式 | 是 |
boolean | 布尔类型 | 略 | 是 |
// 数字测试
let a: number = 0.1
let b: number = 1/3
let c: number = 0
console.log(a)
console.log(b)
console.log(a/c)
//字符串测试
let str1: string = "111"
let str2: string = '222'
let words: string = `${ str1 } , ${ str2 + 1}`
console.log(words)
//boolean测试
let b1: boolean = false
console.log(b1)
//console.log(b1+1) //无法当成数字处理
console.log(`${b1}`)
2.2 复杂数据类型
数组:相同类型数据的集合
//数组
let arr1: number[] = []
arr1[0] = 1
arr1[10] = 2
console.log(arr1)
console.log(arr1[5])
arr1[10] = undefined
console.log(arr1[10])
console.log(arr1
元组:不同类型数据的集合,当我们要往数组里面存入不同类型的数据的时候就用元组
元组有两种,一种是在定义的时候就指明数据的所有类型;另一种则是不指明,这样就可以随意的存入任意类型的数据。
// 定义的时候就指定string和number类型
// let x:[string, number]
let x = ['Runoob', 1] // 是上面声明写法的简写,在声明的同时实例化
//x[5] = false // 编译无法通过
x[10] = 'hello world'
console.log(x);
// 定义的时候不指明类型,可以随意存入数据
let y = []
y[0] = 2
y[1] = 'aa'
y[2] = false
console.log(y)
2.3 联合类型
就是将一个变量同时声明成多种类型,当不确定一个对象具体应该为哪种类型的时候使用联合类型进行声明
let a:string|number = 3
let b = 4
console.log(a+b)
a = 'aa'
if(typeof a == 'string') {
console.log(a+b)
} else {
console.log(a/b) //非数字无法进行除法,这一行编译无法通过
}
实际的用法一般有:
- 对于一个方法的入参,他可能是一个对象,也可能是一组对象,这个时候用联合类型声明如string|string[]。效果同java的可变入参
- 对于某个要用到的对象,无法确定他的实际类型,但是在arkts又不能使用any的情况下,将其声明为可能出现的对象类型。再到需要使用的时候通过instanceof来区分处理。
2.4 空类型和未定义类型
在TypeScript中所有的类型都可以被赋值为空类型null,赋值为空类型时可以和其他同类型对象进行运算,但是无法调用这个对象内部本身的方法,会报空指针异常。
undefined也是同理,当 声明一个对象但是没有赋值的时候他的值就是undefined,使用起来的效果和null是一样的,就不写代码演示了。
let a:number = null
a = 3
a = null
console.log(a + "") // null
console.log(a+2 + "") // 2,在计算时null被当成0
console.log(a*2 + "") // 0
let b:boolean = null
if (b == true) {
console.log(b + ", true")
} else if (b == false) {
console.log(b + ", false")
} else {
console.log(b, ", null") //在做if判断时null既不是true,也不是false
}
let c:string = null
console.log(c)
//console.log(c.length + "") //空对象报错
c = c + "aa"
console.log(c) // 在做字符串运算时,c被当成"null"这个字符串
console.log(c.length + "") // 6
3. 函数
function一般用来声明一个方法,这里着重要说明的一点是,只有当一个方法需要被声明在所有的类或结构体外部时,或者他是匿名函数等没有方法名的函数时,才需要带上function关键字,一般我们在类或者接口里面声明方法的时候都是不需要带的。
这里涉及到一些定义域的关系,我不是很清楚,只作为结论记在这里。
function a(str: string): void {
console.log(str)
}
class b {
//function c() {} //无法通过编译
c(): number {
return 400
}
}
a('aa')
let obj = new b()
console.log(obj.c())
3.1 匿名函数和箭头函数
匿名函数就是指函数没有具体的名字,而是直接声明函数的入参返回值和具体内容。
// 这里这个a不是函数的名称,而是变量的名称,所以是匿名函数
let a = function(n: number): number {
return n+400
}
console.log(a(300))
//在函数定义外加上括号,后面在加上调用的括号就是自调用匿名函数
(function () {
var x = "Hello!!";
console.log(x)
})()
lambda函数(箭头函数)是其更进一步的简写
let b = (n:number) => {
console.log(n)
}
b(123)
// 当你最后一行写上return的时候他就会制定好返回类型,没写就默认是void类型
let c = (n:number) => {
return n*2
}
console.log(c(555))
4. 类和接口
类是语法中最重要的一个单位,他的一般语法如下
class A{
private a: number // 类里面的成员变量在声明时必须要加上访问权限
//constructor() {} //类不允许重载构造方法,只能有一个
constructor(n: number) {
//a = n // 无法过编译
this.a = n //在方法中调用自己的成员变量时,一定要加上this
}
log() {
console.log(a + " ") // 这里实际上指向的是下面代码中的let a
console.log(this.a + "") //这个才是真实指向自己成员变量的a
}
}
let a = new A(5)
//console.log(a.a) // 没有访问权限
a.log()
类的访问权限
TypeScript的类和别的语言的类一样,类本身和里面的方法有对应的访问权限
这里需要声明一点的是,TypeScript和Java不同,它是没有本包的概念的,只有不同文件的区别,所以没有Java默认的本包访问权限
类的访问权限只有两种:仅限本文件内部的默认访问权限;可以给其他文件使用的export访问权限。
方法/成员变量的访问权限只有三种:对外开放的public;可被继承类使用的protect;仅限本类内部的private。
class A {}
export class B {
private a: number
public b: number
private log1() {
}
public log2() {
}
}
接口
TypeScript也可以通过接口来约束一个实体或一个类应该拥有的一些函数
几个语法特性:
- 不允许设置方法的默认实现
- 接口的实现可以不是类而是对象。
- 接口内可以约束变量
interface A {
num: number
log1(): void
log2(n: number): void
}
class B implements A {
num: number
log1() {}
log2(n: number) {
console.log(n + "")
this.num = n
}
}
let c: A = {
num: 0,
log1: function () {},
log2: function (n: number) {
}
}
console.log(c + "") // 类型为object
类的继承
类的继承特性大体和Java一样,通过extends来继承类,通过implements来继承接口,接口可以多继承类只能单继承。
class A {
log() {
console.log("类A")
}
}
interface B {
log(): void
}
interface C {
}
class D extends A implements B,C {
log() { // 重载父类的同名方法
console.log("类D")
}
}
let d = new D()
d.log() //类D
内部类
内部类在声明的时候就必须同时创建对应的实例
class A {
public b = {
log() {
console.log("匿名内部类b")
}
}
public c = class C {
log() {
console.log("实名内部类C")
}
}
//public d = new this.b 无法创建匿名内部类
public d = new this.c
}
let a = new A()
a.d.log()
7. 结构体
TypeScript本身是没有struct这个关键字的,但是arkTs新增了这个关键字,他一般用来声明鸿蒙的自定义组件(其实就是UI类)。
他的绝大部分语法限制和class完全一样
参考材料
从TypeScript到ArkTS的适配规则
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/typescript-to-arkts-migration-guide.md
如何在Typescript实现内部类和接口
https://www.jianshu.com/p/5a9ee0f838f6