華為開發(fā)之ArkTS筆記1 2024-07-02 周二

來源

ArkTS來自TypeScript脆荷,TS就是TypeScript的縮寫时肿。而TypeScript就是來自JavaScript蹄梢,所以所謂的兩種語言其實就是一種語言JavaScript嫉父。當(dāng)然熟掂,還是按照官方的建議缎浇,使用ArkTS就可以了,反正都是JS生態(tài)赴肚。

語言簡介

  • let是變量素跺,const是常量二蓝,定義時帶上初始值,可以推斷類型
let hi1: string = 'hello';
let hi2 = 'hello, world';
const hi3 = 'hello, world! can not change';
  • 數(shù)字的類型是number指厌,不用區(qū)分整數(shù)和浮點數(shù)刊愚;默認(rèn)是10進(jìn)制;16進(jìn)制用0x開頭踩验;

  • boolean類型由true和false兩個邏輯值組成鸥诽。

  • 字符串字面量由單引號(')或雙引號(")之間括起來的零個或多個字符組成(實際使用優(yōu)先用雙引號)。字符串字面量還有一特殊形式箕憾,是用反向單引號(`)括起來的模板字面量牡借。字符串插值用${}

let s1 = 'Hello, world!\n';
let s2 = 'this is a string';
let a = 'Success';
let s3 = `The result is ${a}`;
  • Object類型是所有引用類型的基類型。任何值袭异,包括基本類型的值(它們會被自動裝箱)钠龙,都可以直接被賦給Object類型的變量。

  • 數(shù)組Array類型

let names: string[] = ['Alice', 'Bob', 'Carol'];
  • enum類型御铃,又稱枚舉類型碴里,是預(yù)先定義的一組命名值的值類型,其中命名值又稱為枚舉常量上真。
enum ColorSet { Red, Green, Blue }
let c: ColorSet = ColorSet.Red;
  • union類型咬腋,即聯(lián)合類型,是由多個類型組合成的引用類型睡互。聯(lián)合類型包含了變量可能的所有類型根竿。(這個有點特殊,合適的地方用起來)
class Cat { sleep () {}; meow () {} }
class Dog { sleep () {}; bark () {} }
class Frog { sleep () {}; leap () {} }

type Animal = Cat | Dog | Frog | number

let animal: Animal = new Frog();
if (animal instanceof Frog) {
  let frog: Frog = animal as Frog; // animal在這里是Frog類型
  animal.leap();
  frog.leap();
  // 結(jié)果:青蛙跳了兩次
}

animal.sleep (); // 任何動物都可以睡覺
  • Aliases類型為匿名類型(數(shù)組就珠、函數(shù)犀填、對象字面量或聯(lián)合類型)提供名稱,或為已有類型提供替代名稱嗓违。
type Matrix = number[][];
type Handler = (s: string, no: number) => string;
type Predicate <T> = (x: T) => Boolean;
type NullableObject = Object | null;
  • if 要帶括號,條件可以是任何表達(dá)式图贸,會隱式轉(zhuǎn)換為boolean類型(這點不如Swift)

  • switch語句的break不應(yīng)該省略蹂季;如果沒有break語句,則執(zhí)行switch中的下一個label對應(yīng)的代碼塊疏日。(這點不如Swift)

  • 使用for-of語句可遍歷數(shù)組或字符串偿洁。

for (let ch of 'a string object') {
  /* process ch */
}
  • 錯誤處理:try catch finally結(jié)構(gòu)
function processData(s: string) {
  let error: Error | null = null;  

  try {
    console.log('Data processed: ' + s);
    // ...
    // 可能發(fā)生異常的語句
    // ...
  } catch (e) {
    error = e as Error;
    // ...
    // 異常處理
    // ...
  } finally {
    if (error != null) {
      console.log(`Error caught: input='${s}', message='${error.message}'`);
    }
  }
}
  • 函數(shù)可選參數(shù)的格式可為name?: Type
function hello(name?: string) {
  if (name == undefined) {
    console.log('Hello!');
  } else {
    console.log(`Hello, ${name}!`);
  }
}
  • 可選參數(shù)的另一種形式為設(shè)置的參數(shù)默認(rèn)值。如果在函數(shù)調(diào)用中這個參數(shù)被省略了沟优,則會使用此參數(shù)的默認(rèn)值作為實參涕滋。
function multiply(n: number, coeff: number = 2): number {
  return n * coeff;
}
multiply(2);  // 返回2*2
multiply(2, 3); // 返回2*3
  • 函數(shù)的最后一個參數(shù)可以是rest參數(shù)。使用rest參數(shù)時挠阁,允許函數(shù)或方法接受任意數(shù)量的實參宾肺。
function sum(...numbers: number[]): number {
  let res = 0;
  for (let n of numbers)
    res += n;
  return res;
}

sum() // 返回0
sum(1, 2, 3) // 返回6
  • 如果可以從函數(shù)體內(nèi)推斷出函數(shù)返回類型溯饵,則可在函數(shù)聲明中省略標(biāo)注返回類型。
// 顯式指定返回類型
function foo(): string { return 'foo'; }

// 推斷返回類型為string
function goo() { return 'goo'; }
  • 不需要返回值的函數(shù)的返回類型可以顯式指定為void或省略標(biāo)注锨用。這類函數(shù)不需要返回語句丰刊。
function hi1() { console.log('hi'); }
function hi2(): void { console.log('hi'); }
  • 閉包是由函數(shù)及聲明該函數(shù)的環(huán)境組合而成的。該環(huán)境包含了這個閉包創(chuàng)建時作用域內(nèi)的任何局部變量增拥。
    在下例中啄巧,z是執(zhí)行f時創(chuàng)建的g箭頭函數(shù)實例的引用。g的實例維持了對它的環(huán)境的引用(變量count存在其中)掌栅。因此秩仆,當(dāng)z被調(diào)用時,變量count仍可用猾封。
function f(): () => number {
  let count = 0;
  let g = (): number => { count++; return count; };
  return g;
}

let z = f();
z(); // 返回:1
z(); // 返回:2
  • 我們可以通過編寫重載澄耍,指定函數(shù)的不同調(diào)用方式。具體方法為忘衍,為同一個函數(shù)寫入多個同名但簽名不同的函數(shù)頭逾苫,函數(shù)實現(xiàn)緊隨其后。
function foo(x: number): void;            /* 第一個函數(shù)定義 */
function foo(x: string): void;            /* 第二個函數(shù)定義 */
function foo(x: number | string): void {  /* 函數(shù)實現(xiàn) */
}

foo(123);     //  OK枚钓,使用第一個定義
foo('aa'); // OK铅搓,使用第二個定義
  • 為了減少運行時的錯誤和獲得更好的執(zhí)行性能,ArkTS要求所有字段在聲明時或者構(gòu)造函數(shù)中顯式初始化搀捷。如果可能為空星掰,要加?
class Person {
  name?: string // 可能為`undefined`

  setName(n:string): void {
    this.name = n;
  }

  // 編譯時錯誤:name可以是"undefined"嫩舟,所以將這個API的返回值類型標(biāo)記為string
  getNameWrong(): string {
    return this.name;
  }

  getName(): string | undefined { // 返回類型匹配name的類型
    return this.name;
  }
}

let jack = new Person();
// 假設(shè)代碼中沒有對name賦值氢烘,例如調(diào)用"jack.setName('Jack')"

// 編譯時錯誤:編譯器認(rèn)為下一行代碼有可能會訪問undefined的屬性,報錯
jack.getName().length;  // 編譯失敗

jack.getName()?.length; // 編譯成功家厌,沒有運行時錯誤
  • setter和getter可用于提供對對象屬性的受控訪問播玖。
class Person {
  name: string = ''
  private _age: number = 0
  get 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; // 設(shè)置無效age值會拋出錯誤
  • 關(guān)鍵字super可用于訪問父類的實例字段、實例方法和構(gòu)造函數(shù)饭于。在實現(xiàn)子類功能時蜀踏,可以通過該關(guān)鍵字從父類中獲取所需接口
class RectangleSize {
  protected height: number = 0
  protected width: number = 0

  constructor (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); // 父類構(gòu)造函數(shù)的調(diào)用
    this.color = c;
  }

  draw() {
    super.draw(); // 父類方法的調(diào)用
    // super.height -可在此處使用
    /* 填充矩形 */
  }
}
  • 子類可以重寫其父類中定義的方法的實現(xiàn)。重寫的方法必須具有與原始方法相同的參數(shù)類型和相同或派生的返回類型掰吕。
class RectangleSize {
  // ...
  area(): number {
    // 實現(xiàn)
    return 0;
  }
}
class Square extends RectangleSize {
  private side: number = 0
  area(): number {
    return this.side * this.side;
  }
}
  • 通過重載簽名果覆,指定方法的不同調(diào)用。具體方法為殖熟,為同一個方法寫入多個同名但簽名不同的方法頭局待,方法實現(xiàn)緊隨其后。
class C {
  foo(x: number): void;            /* 第一個簽名 */
  foo(x: string): void;            /* 第二個簽名 */
  foo(x: number | string): void {  /* 實現(xiàn)簽名 */
  }
}
let c = new C();
c.foo(123);     // OK,使用第一個簽名
c.foo('aa'); // OK钳榨,使用第二個簽名
  • 我們可以通過編寫重載簽名舰罚,指定構(gòu)造函數(shù)的不同調(diào)用方式。具體方法為重绷,為同一個構(gòu)造函數(shù)寫入多個同名但簽名不同的構(gòu)造函數(shù)頭沸停,構(gòu)造函數(shù)實現(xiàn)緊隨其后。
class C {
  constructor(x: number)             /* 第一個簽名 */
  constructor(x: string)             /* 第二個簽名 */
  constructor(x: number | string) {  /* 實現(xiàn)簽名 */
  }
}
let c1 = new C(123);      // OK昭卓,使用第一個簽名
let c2 = new C('abc');    // OK愤钾,使用第二個簽名
  • 對象字面量是一個表達(dá)式,可用于創(chuàng)建類實例并提供一些初始值候醒。它在某些情況下更方便能颁,可以用來代替new表達(dá)式。(JS對象的本質(zhì)是一個Map)
class C {
  n: number = 0
  s: string = ''
}

let c: C = {n: 42, s: 'foo'};
  • 泛型Record<K, V>用于將類型(鍵類型)的屬性映射到另一個類型(值類型)倒淫。常用對象字面量來初始化該類型的值:類型K可以是字符串類型或數(shù)值類型伙菊,而V可以是任何類型。
let map: Record<string, number> = {
  'John': 25,
  'Mary': 21,
}

map['John']; // 25
interface PersonInfo {
  age: number
  salary: number
}
let map: Record<string, PersonInfo> = {
  'John': { age: 25, salary: 10},
  'Mary': { age: 21, salary: 20}
}
  • 接口屬性可以是字段敌土、getter镜硕、setter或getter和setter組合的形式。屬性字段只是getter/setter對的便捷寫法返干。以下表達(dá)方式是等價的:
interface Style {
  color: string
}

class StyledRectangle implements Style {
  color: string = ''
}
interface Style {
  get color(): string
  set color(x: string)
}

class StyledRectangle implements Style {
  private _color: string = ''
  get color(): string { return this._color; }
  set color(x: string) { this._color = x; }
}
  • 接口可以繼承其他接口
interface Style {
  color: string
}

interface ExtendedStyle extends Style {
  width: number
}
  • 泛型類型的類型參數(shù)可以綁定兴枯。例如,HashMap<Key, Value>容器中的Key類型參數(shù)必須具有哈希方法矩欠,即它應(yīng)該是可哈希的财剖。
interface Hashable {
  hash(): number
}
class HasMap<Key extends Hashable, Value> {
  public set(k: Key, v: Value) {
    let h = k.hash();
    // ...其他代碼...
  }
}
  • 使用泛型函數(shù)可編寫更通用的代碼。比如返回數(shù)組最后一個元素的函數(shù):
function last<T>(x: T[]): T {
  return x[x.length - 1];
}

// 顯式設(shè)置的類型實參
last<string>(['aa', 'bb']);
last<number>([1, 2, 3]);

// 隱式設(shè)置的類型實參
// 編譯器根據(jù)調(diào)用參數(shù)的類型來確定類型實參
last([1, 2, 3]);
  • 泛型類型的類型參數(shù)可以設(shè)置默認(rèn)值癌淮。這樣可以不指定實際的類型實參躺坟,而只使用泛型類型名稱。下面的示例展示了類和函數(shù)的這一點乳蓄。
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();
// 此函數(shù)在語義上等價于下面的調(diào)用
foo<number>();
  • 可以為空值的變量定義為聯(lián)合類型T | null咪橙。
let x: number | null = null;
x = 1;    // ok
x = null; // ok
if (x != null) { /* do something */ }
  • 空值合并二元運算符??用于檢查左側(cè)表達(dá)式的求值是否等于null或者undefined。如果是虚倒,則表達(dá)式的結(jié)果為右側(cè)表達(dá)式匣摘;否則,結(jié)果為左側(cè)表達(dá)式裹刮。換句話說,a ?? b等價于三元運算符(a != null && a != undefined) ? a : b庞瘸。
class Person {
  // ...
  nick: string | null = null
  getNick(): string {
    return this.nick ?? '';
  }
}
  • 在訪問對象屬性時捧弃,如果該屬性是undefined或者null,可選鏈運算符會返回undefined。在以下示例中违霞,如果一個Person的實例有不為空的spouse屬性嘴办,且spouse有不為空的nick屬性,則輸出spouse.nick买鸽。否則涧郊,輸出undefined:
class Person {
  nick: string | null = null
  spouse?: Person

  constructor(nick: string) {
    this.nick = nick;
    this.spouse = undefined;
  }
}

let p: Person = new Person('Alice');
p.spouse?.nick; // undefined
  • 程序可劃分為多組編譯單元或模塊。
    每個模塊都有其自己的作用域眼五,即妆艘,在模塊中創(chuàng)建的任何聲明(變量、函數(shù)看幼、類等)在該模塊之外都不可見批旺,除非它們被顯式導(dǎo)出。
    與此相對诵姜,從另一個模塊導(dǎo)出的變量汽煮、函數(shù)、類棚唆、接口等必須首先導(dǎo)入到模塊中暇赤。

  • 可以使用關(guān)鍵字export導(dǎo)出頂層的聲明,在導(dǎo)入時要加{}宵凌。

export class Point {
  x: number = 0
  y: number = 0
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}
export let Origin = new Point(0, 0);
export function Distance(p1: Point, p2: Point): number {
  return Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
}
  • 假設(shè)模塊具有路徑“./utils”和導(dǎo)出實體“X”和“Y”鞋囊。
    (1)導(dǎo)入綁定* as A表示綁定名稱“A”,通過A.name可訪問從導(dǎo)入路徑指定的模塊導(dǎo)出的所有實體:
import * as Utils from './utils'
Utils.X // 表示來自Utils的X
Utils.Y // 表示來自Utils的Y

(2)導(dǎo)入綁定{ ident1, ..., identN }表示將導(dǎo)出的實體與指定名稱綁定摆寄,該名稱可以用作簡單名稱:

import { X, Y } from './utils'
X // 表示來自utils的X
Y // 表示來自utils的Y

(3)如果標(biāo)識符列表定義了ident as alias失暴,則實體ident將綁定在名稱alias下:

import { X as Z, Y } from './utils'
Z // 表示來自Utils的X
Y // 表示來自Utils的Y
X // 編譯時錯誤:'X'不可見
  • import()語法通常稱為動態(tài)導(dǎo)入dynamic import,是一種類似函數(shù)的表達(dá)式微饥,用來動態(tài)導(dǎo)入模塊逗扒。以這種方式調(diào)用,將返回一個promise欠橘。
let modulePath = prompt("Which module to load?");
import(modulePath)
.then(obj => <module object>)
.catch(err => <loading error, e.g. if no such module>)
  • 如果在異步函數(shù)中矩肩,可以使用let module = await import(modulePath)。
// say.ts
export function hi() {
  console.log('Hello');
}
export function bye() {
  console.log('Bye');
}
async function test() {
  let ns = await import('./say');
  let hi = ns.hi;
  let bye = ns.bye;
  hi();
  bye();
}
  • HarmonyOS SDK提供的開放能力(接口)也需要在導(dǎo)入聲明后使用肃续∈蜷荩可直接導(dǎo)入接口模塊來使用該模塊內(nèi)的所有接口能力,例如:(這種方式應(yīng)該是過時了)
import UIAbility from '@ohos.app.ability.UIAbility';
  • 導(dǎo)入Kit下多個模塊的接口能力始锚。例如:(單個的包含在這里刽酱; 所有的*的方式最好不要用)
import { UIAbility, Ability, Context } from '@kit.AbilityKit';
  • 關(guān)鍵字this只能在類的實例方法中使用。
class A {
  count: string = 'a'
  m(i: string): void {
    this.count = i;
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞧捌,一起剝皮案震驚了整個濱河市棵里,隨后出現(xiàn)的幾起案子润文,更是在濱河造成了極大的恐慌,老刑警劉巖殿怜,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件典蝌,死亡現(xiàn)場離奇詭異,居然都是意外死亡头谜,警方通過查閱死者的電腦和手機(jī)骏掀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柱告,“玉大人截驮,你說我怎么就攤上這事∧┘觯” “怎么了侧纯?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長甲脏。 經(jīng)常有香客問我眶熬,道長,這世上最難降的妖魔是什么块请? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任娜氏,我火速辦了婚禮,結(jié)果婚禮上墩新,老公的妹妹穿的比我還像新娘贸弥。我一直安慰自己,他們只是感情好海渊,可當(dāng)我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布绵疲。 她就那樣靜靜地躺著,像睡著了一般臣疑。 火紅的嫁衣襯著肌膚如雪盔憨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天讯沈,我揣著相機(jī)與錄音郁岩,去河邊找鬼。 笑死缺狠,一個胖子當(dāng)著我的面吹牛问慎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挤茄,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼如叼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了穷劈?” 一聲冷哼從身側(cè)響起薇正,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤片酝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后挖腰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡练湿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年猴仑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肥哎。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡辽俗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篡诽,到底是詐尸還是另有隱情崖飘,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布杈女,位于F島的核電站朱浴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏达椰。R本人自食惡果不足惜翰蠢,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望啰劲。 院中可真熱鬧梁沧,春花似錦、人聲如沸蝇裤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栓辜。三九已至恋拍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啃憎,已是汗流浹背芝囤。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留辛萍,地道東北人悯姊。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像贩毕,于是被迫代替她去往敵國和親悯许。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容