专门做二手手机的网站有哪些,wordpress 知更鸟,大气网络公司网站模板,新手搭建网站教程【HarmonyOS】HarmonyOS NEXT学习日记#xff1a;二、ArkTs语法
众所周知TS是JS的超集,而ArkTs则可以理解为是Ts的超集。他们的基础都基于JS#xff0c;所以学习之前最好就JS基础。我的学习重点也是放在ArkTs和JS的不同点上。
文章主要跟着官方文档学习#xff0c;跳过了一…【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)//2enum ColorSet { White 0xFF, Grey 0x7F, Black 0x00 }
let c: ColorSet ColorSet.Black;
console.log(c)//0x00Union类型
联合类型是由多个类型组合成的引用类型。联合类型包含了变量可能的所有类型。 比如我想要一个数组既可以储存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()//输出meRest参数
用法与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 )//2getter和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类型的对象字面量
泛型RecordK, V用于将类型键类型的属性映射到另一个类型值类型。常用对象字面量来初始化该类型的值
let map: Recordstring, number {John: 25,Mary: 21,
}map[John]; // 25类型K可以是字符串类型或数值类型而V可以是任何类型.
interface PersonInfo {age: numbersalary: number
}
let map: Recordstring, 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 CustomStackElement {//这里定义了一个Element形参作为类型public push(e: Element):void {//内部的push方法接受的参数使用Element为类型// ...}
}let s new CustomStackstring();//在实例化的时候传入Element的实参string用来当做push方法的入参类型
s.push(hello);泛型约束
泛型类型的类型参数可以被限制只能取某些特定的值。例如MyHashMapKey, Value这个类中的Key类型参数必须具有hash方法。
interface Hashable {hash(): number
}
class MyHashMapKey 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 lastT(x: T[]): T {return x[x.length - 1];
}现在该函数可以与任何数组一起使用。
// 显式设置的类型实参
laststring([aa, bb]);
lastnumber([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 BaseSomeType implements InterfaceSomeType { }function fooT number(): T {// ...
}
foo();
// 此函数在语义上等价于下面的调用
foonumber();