TypeScript
- VS code 自動編譯 TS 文件
- 第一步
tsc --init
生成 tsconfig.json 改"outdir": "./js"
- 第二步 任務 - 運行任務 監(jiān)視
tsconfig.json
- 第一步
數(shù)據(jù)類型
-
TS 中為了使編寫的代碼更加規(guī)范凹联,更有利于維護,增加了類型校驗嚣艇,在 TS 中主要提供了以下數(shù)據(jù)類型
- 布爾類型 boolean
- 數(shù)字類型 number
- 字符串類型 string
- 數(shù)組類型 array
- 元組類型 tuple
- 枚舉類型 enum
- 任意類型 any
- null 和 undefined
- void 類型
- nerve 類型
-
數(shù)組類型
- let arr: number[] = [1, 2, 3]
- let arr: Array<number> = [1, 2, 3]
-
元組類型
- let arr: [number, string] = [1, "hello"]
-
枚舉類型(enum)
隨著計算機的不斷普及棋凳,程序不僅只用于數(shù)值計算诫咱,還更廣泛地用于處理非數(shù)值的數(shù)據(jù)莫辨。
例如性別抒寂、年齡结啼、月份、顏色等屈芜,都不是數(shù)值數(shù)據(jù)郊愧。
在其它程序中用自然語言中有相應含義的單詞來代表某一狀態(tài),則程序就很容易閱讀和理解井佑。
也就是說属铁,實現(xiàn)考慮到某一變量可能取的值,盡量用自然語言中含義清楚的單詞來表示它的每一個值躬翁。
這種方法成為枚舉方法焦蘑,用這種方法定義的類型稱枚舉類型。
- 定義枚舉類型的方法
ts enum 枚舉名 { 標識符[=整型常數(shù)], 標識符[=整型常數(shù)], ... 標識符[=整型常數(shù)], }
- 使用的方法
```ts
enum Color {
blue,
red = 30,
'orange'
};let a: Color = Color.blue console.log(a) // 0 let b: Color = Color.red console.log(b) // 30 let c: Color = Color.orange console.log(c) // 31 ```
-
任意類型
- 用法
let oBox: any = document.getElementById('box'); oBox.style.color = 'red'; // oBox 不指定類型或者指定 Object 類型都會報錯盒发,所以需要指定 any 類型例嘱。
- 用法
-
null 和 undefined
- 用法
let num1: undefined; console.log(num1); let num2: number | undefined num2 = 123 console.log(num2)
- 用法
-
void 類型
- 用法
ts function run(): void { console.log("ok") } //表示 run 函數(shù)沒有返回值
- 用法
-
Never 類型
- Never 類型是那些總是會拋出異常或根本就不會有返回值的函數(shù)表達式或箭頭函數(shù)表達式的返回值類型
- 是其他類型(包括 null 和 undefined)的子類型宁舰,代表從不會出現(xiàn)的值
- 這意味著聲明 never 的變量只能被 never 類型所賦值拼卵。
- 用法:
// 返回never的函數(shù)必須存在無法達到的終點 function error(message: string): never { throw new Error(message); } // 推斷的返回值類型為never function fail() { return error("Something failed"); } // 返回never的函數(shù)必須存在無法達到的終點 function infiniteLoop(): never { while (true) { } }
函數(shù)
- TS 中函數(shù)的定義
- 函數(shù)聲明式
function run(): string { return 'abc' }
- 匿名函數(shù)
- 函數(shù)聲明式
- 方法可選參數(shù)
- ES5 里面方法的實參和形參可以不一樣,但是 TS 中必須一樣蛮艰,如果不一樣就需要配置可選參數(shù)腋腮。
- 注意:可選參數(shù)必須配置到參數(shù)的最后面。
function getInfo(name: string, age?: number) { if(age) { return `${name} --- ${age}` } else { return `${name} --- 年齡保密` } } alert(getInfo("張三"))
- 默認參數(shù)
- ES5 中無法設置默認參數(shù),ES6 和 TS 中都可以設置默認參數(shù)
function getInfo(name: string, age: number = 20) { if(age) { return `${name} --- ${age}` } else { return `${name} --- 年齡保密` } } alert(getInfo("張三"))
- ES5 中無法設置默認參數(shù),ES6 和 TS 中都可以設置默認參數(shù)
- 剩余參數(shù)
- 利用 三點運算符 獲取剩余參數(shù)
function sum(...result: number[]): number { let sum = 0 result.forEach(item => { sum += item }) return sum } alert(sum(1, 2, 3, 4))
- 利用 三點運算符 獲取剩余參數(shù)
- TS函數(shù)重載
- Java 中方法的重載即寡,重載指的是兩個或者兩個以上同名的函數(shù)徊哑,但是他們的參數(shù)不一樣,這時會出現(xiàn)函數(shù)重載的情況聪富。
- TypeScript 中的重載实柠,通過為同一個函數(shù)提供多個函數(shù)類型定義來實現(xiàn)多種功能的目的
function getInfo(name: string): string; function getInfo(age: number): number; function getInfo(str: any): any { if(typeof str === 'string') { return '我叫:' + str; } else { return '我的年齡是:' + str } }
- 箭頭函數(shù)
ES5 創(chuàng)建對象和繼承
- 原型鏈 + 對象冒充的組合繼承模式
- 繼承構造函數(shù)及其原型鏈里面的屬性和方法
function Person(name, age) { this.name = name; this.age = age; this.run = function () { alert(this.name + "在運動") } } Person.prototype.sex = "男" Person.prototype.work = function() { alert(this.name + "在工作") } function Web(name, age) { // 對象冒充實現(xiàn)繼承構造函數(shù)的屬性和方法 Person.call(this, name, age) } // 實現(xiàn)繼承其原型鏈上的屬性和方法 - 下面兩種方式都可以實現(xiàn) // Web.prototype = new Person() Web.prototype = Person.prototype var w = new Web("張三"); w.run() w.work()
- 繼承構造函數(shù)及其原型鏈里面的屬性和方法
TS 中的類
- TS 中類的定義
class Person { name: string; constructor(name: string) { this.name = name } run():void { alert(this.name) } }
- TS 中實現(xiàn)繼承 - extends、super
class Person { name: string; constructor(name: string) { this.name = name } run():void { alert(`${this.name}在運動`) } } class Web extends Person { constructor(name: string) { // 初始化父類的構造函數(shù) super(name) } work() { alert(`${this.name}在工作`) } }
- 類里面的修飾符
- TS 里面定義屬性的時候給我們提供了三種修飾符
- public:共有 在類里面善涨、子類窒盐、類外面都可以訪問
- protected:保護類型 在類里面、子類里面可以訪問钢拧,在類外面無法訪問
- private:私有 在類里面可以訪問蟹漓,子類、類外部都無法訪問
- TS 里面定義屬性的時候給我們提供了三種修飾符
靜態(tài)屬性源内、靜態(tài)方法
- static 關鍵字聲明屬性或者方法
class Person { public name: string; public age: number = 20; static sex = "男" constructor(name: string) { this.name = name } run() { alert(`${this.name}在運動`) } work() { alert(`${this.name}在工作`) } // 靜態(tài)方法 里面無法直接調(diào)用類里面的屬性 static print() { // alert("print方法" + this.age) alert("print方法" + Person.sex) } } Person.print()
多態(tài)
- 父類定義一個方法不去實現(xiàn)葡粒,讓繼承它的子類去實現(xiàn),每一個子類有不同的表現(xiàn)
- 多態(tài)也是繼承的一種表現(xiàn)膜钓,多態(tài)屬于繼承
class Animal { name: string; constructor(name: string) { this.name = name } eat() { // 具體吃什么嗽交,不知道,繼承它的子類去實現(xiàn)颂斜,每一個子類的表現(xiàn)不一樣 console.log("吃的方法") } } class Dog extends Animal { constructor(name: string) { super(name) } eat() { return this.name + '吃糧食' } } class Cat extends Animal { constructor(name: string) { super(name) } eat() { return this.name + '吃老鼠' } }
抽象類
- TS 中的抽象類:它是提供其他類繼承的基類夫壁,不能直接被實例化
- 用 abstract 關鍵字定義抽象類和抽象方法,抽象類中的抽象方法不包含具體實現(xiàn)并且必須在派生類中實現(xiàn)
- abstract 抽象方法只能放在抽象類里面
- 抽象類和抽象方法用來定義標準 -- Animal 這個類要求它的子類必須包含 eat 方法
abstract class Animal { public name: string; constructor(name: string) { this.name = name } abstract eat(): any; // 抽象方法不包含具體實現(xiàn)并且必須在派生類中實現(xiàn) } class Dog extends Animal { constructor(name: string) { super(name) } // 抽象類的子類必須實現(xiàn)抽象類里面的抽象方法 eat() { return this.name + '吃糧食' } } class Cat extends Animal { constructor(name: string) { super(name) } // 抽象類的子類必須實現(xiàn)抽象類里面的抽象方法 // 不包含 eat 抽象方法沃疮,所以報錯了 // 非抽象類“Cat”不會實現(xiàn)繼承自“Animal”類的抽象成員“eat”盒让。 } // let a = new Animal() // 不能這樣用 let dog = new Dog("大黃") alert(dog.eat())
接口
接口的作用:在面向對象的編程中,接口是一種規(guī)范的定義司蔬,它定義了行為和動作的規(guī)范邑茄,在程序設計里,接口起到一種限制和規(guī)范的作用俊啼。接口定義了某一批類所需要遵守的規(guī)范肺缕,接口不關心這些類的內(nèi)部狀態(tài)數(shù)據(jù),也不關心這些類里的方法的實現(xiàn)細節(jié)授帕,它之規(guī)定這批類里必須提供某些方法同木,提供這些方法的類就可以滿足實際需要。Typescript 中的接口類似于 Java豪墅,同事還增加了更加靈活的接口類型泉手,包括屬性、函數(shù)偶器、可索引和類等。
- 屬性接口
- TS 中定義方法傳入?yún)?shù)
function printLabel(label: string): void {} printLabel("哈哈")
- TS 中定義方法傳入?yún)?shù)對 json 進行約束
function printLabel(labelInfo: {label: string}): void {} printLabel("哈哈") // 錯誤寫法 printLabel({label: "哈哈"}) // 正確寫法
- 對批量方法傳入?yún)?shù)進行約束
- 接口:行為和動作的規(guī)范,對批量方法進行約束
interface FullName { firstName: string; secondName: string; } function printName(name: FullName) { // 必須傳入對象 firstName 和 secondName console.log(name.firstName + '---' + name.secondName) }
- TS 中定義方法傳入?yún)?shù)
- 可選屬性
interface FullName { firstName: string; secondName?: string; }
- 函數(shù)類型接口:對方法傳入的參數(shù)以及返回值進行約束
- 加密的函數(shù)類型接口
interface encrypt { (key: string, value: string): string } let run: encrypt = function(key: string, value: string): string { return key + value }
- 可索引接口:數(shù)組屏轰、對象的約束 (不常用)
- 可索引接口對數(shù)組的約束
interface UserArr { [index: number]: string; } let arr: UserArr = ['123', 'bbb'] console.log(arr[0])
- 可索引接口對對象的約束
interface UserObj { [index: string]: string; } let obj: UserObj = {name: '張三'} console.log(obj.name)
- 加密的函數(shù)類型接口
- 類類型接口:對類的約束 和 抽象類有點類似
interface Animal { name: string; eat(str: string): void } class Dog implements Animal { name: string; constructor(name: string) { this.name = name } eat() { console.log(this.name + '吃肉') } }
- 接口擴展:接口可以繼承接口
interface Animal { eat(): void; } interface Person extends Animal { work(): void; } class Programmer { public name: string; constructor(name: string) { this.name = name } coding(code: string) { console.log(this.name + code) } } class Web extends Programmer implements Person { constructor(name: string) { super(name) this.name = name } eat() { console.log(this.name + '吃饅頭') } work() { console.log(this.name + '寫代碼') } } let w = new Web("小黑") w.eat() w.work() w.coding("寫 TS 代碼")
泛型
泛型:軟件工程中颊郎,我們不僅要創(chuàng)建一直的定義良好的 API,同時也要考慮可重用性霎苗。組件不僅能夠支持當前的數(shù)據(jù)類型姆吭,同事也能支持未來的數(shù)據(jù)類型,著在創(chuàng)建大型系統(tǒng)時為你提供十分靈活的功能唁盏。
在像 C# 和 Java 這樣的語言中内狸,可以使用泛型來創(chuàng)建可重用的組件,一個組件可以支持多種類型的數(shù)據(jù)厘擂。這樣用戶就可以以自己的數(shù)據(jù)類型來使用組件昆淡。
通俗理解:泛型就是解決類 接口 方法的復用性、以及對不特定類型的支持刽严。
泛型的定義
- T 表示泛型昂灵,具體什么類型是調(diào)用這個方法的時候決定的
泛型函數(shù)
function getData<T>(value: T):T {
return value
}
getData<number>(123)
泛型類:
class MinClass<T> {
public list: T[] = []
add(value: T):void {
this.list.push(value)
}
min():T {
let minNum = this.list[0];
for(let i = 0; i < this.list.length; i++) {
if (minNum > this.list[i]) {
minNum = this.list[i]
}
}
return minNum
}
}
let m1 = new MinClass<number>();
m1.add(1)
m1.add(14)
m1.add(5)
alert(m1.min())
泛型接口
- 基本使用
interface ConfigFn<T> { (value: T): T } function getData<T>(value: T):T { return value } var myGetData:ConfigFn<string> = getData; myGetData('20') // myGetData(20) // 錯誤 // getData<string>('1234') // 錯誤·ts
- 數(shù)據(jù)庫操作
class ArticleCate { title: string | undefined; desc: string | undefined; status: number | undefined; constructor(params: { title: string | undefined, desc: string | undefined, status?: number |undefined, }) { this.title = params.title this.desc = params.desc this.status = params.status } } class MysqlDb<T> { add(info: T):boolean { console.log(info) return true } updated(id: number, info: T): boolean { console.log(info) return true } } // 添加操作 let a = new ArticleCate({ title: "分類", desc: '123', }) let db = new MysqlDb<ArticleCate>() db.add(a) // 修改操作 let b = new ArticleCate({ title: "分類2", desc: '456', status: 1, }) db.updated(123, b)
綜合使用
功能:定義一個操作數(shù)據(jù)庫的庫,支持 Mysql舞萄、Mssql眨补、MongDB
要求1:Mysql、Mssql倒脓、MongDB 功能一樣撑螺,都有 add、update崎弃、delete实蓬、get 方法
注意:約束統(tǒng)一的規(guī)范,以及代碼重用
解決方案:需要約束規(guī)范所以要定義接口吊履,需要代碼重用所以用到泛型
1安皱、接口:在面向對象的編程中,接口是一種規(guī)范
2艇炎、泛型 通俗理解:泛型就是解決類 接口 方法的復用性
interface DBI<T> {
add(info: T): boolean;
update(info: T, id: number): boolean;
delete(id: number): boolean;
get(id: number): any[];
}
// 定義一個操作 mysql 數(shù)據(jù)庫的類 注意:要實現(xiàn)泛型接口酌伊,這個類也應該是一個泛型
class MysqlDb<T> implements DBI<T> {
constructor() {
console.log("數(shù)據(jù)庫建立連接")
}
add(info: T): boolean {
console.log(info)
return true
}
update(info: T, id: number): boolean {
throw new Error("Method not implemented.");
}
delete(id: number): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
let list = [
{
title: 'xxxx',
desc: 'xxxxx',
},
{
title: 'xxxx',
desc: 'xxxxx',
},
]
return list
}
}
// 定義已個操作 mssql 數(shù)據(jù)庫的類
class MssqlDb<T> implements DBI<T> {
add(info: T): boolean {
console.log(info)
return true
}
update(info: T, id: number): boolean {
throw new Error("Method not implemented.");
}
delete(id: number): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
throw new Error("Method not implemented.");
}
}
// 操作用戶表 定義一個 User 類和數(shù)據(jù)表做映射
class User {
username: string | undefined;
password: string | undefined;
}
let u = new User()
u.username = "張三"
u.password = "123456"
let oMysql = new MysqlDb<User>()
oMysql.add(u)
let oMssql = new MssqlDb<User>();
oMssql.add(u)
// 獲取 User 表 id 為4的數(shù)據(jù)
let data = oMysql.get(4)
console.log(data)
模塊
模塊的概念
- 官方:
- 關于術語的一點說明:請務必注意一點,Typescript 1.5里面語名已經(jīng)發(fā)生變化缀踪。"內(nèi)部模塊"現(xiàn)在稱作"命名空間"
- "外部模塊"現(xiàn)在則簡稱為"模塊"居砖,模塊在其自身的作用域里執(zhí)行,而不是在全局作用域里
- 這意味著定義在一個模塊里的變量驴娃、函數(shù)奏候、類等等在模塊外部都是不可見的,除非你明確地使用 export 形式之一導出它們唇敞。
- 相反蔗草,如果想使用其他模塊導出的變量咒彤、函數(shù)、類咒精、接口等的時候镶柱,你必須要導入它們,可以使用 import 形式之一模叙。
- 理解:
- 我們可以把一些公共的功能單獨抽離成一個文件作為一個模塊
- 模塊里的變量歇拆、函數(shù)、類等默認是私有的范咨,如果我們要在外部訪問模塊里面的數(shù)據(jù)(變量故觅、函數(shù)、類)渠啊,
- 我們需要通過 export 暴露模塊里面的數(shù)據(jù)(變量输吏、函數(shù)、類)
- 暴露后我們通過 import 引入模塊就可以使用模塊里面暴露的數(shù)據(jù)(變量昭抒、函數(shù)评也、類)
命名空間
- 在代碼量較大的情況下,為了避免各種變量命名相沖突灭返,可將相似功能的函數(shù)盗迟、類、接口等放置到命名空間內(nèi)
- 同 Java 的包熙含、.net 的命名空間一樣罚缕,TypeScript 的命名空間可以將代碼包裹起來,只對外暴露需要外部訪問的對象怎静,命名空間內(nèi)的對象通過 export 暴露出去
命名空間和模塊的區(qū)別
- 命名空間:內(nèi)部模塊邮弹,主要用于組織代碼,避免命名沖突
- 模塊:ts的外部模塊的簡稱蚓聘,側重代碼的重用腌乡,一個模塊里可能會有多個命名空間
namespace A { interface Animal { } export class Cat { eat() {} } } let a = new A.Cat()
裝飾器
- 裝飾器:裝飾器是一種特殊類型的聲明,它能夠被附加到類聲明夜牡、方法与纽、屬性或參數(shù)上,可以修改類的行為塘装。
- 通俗的講急迂,裝飾器就是一個方法,可以注入到類蹦肴、方法僚碎、屬性參數(shù)上來擴展類、屬性阴幌、方法勺阐、參數(shù)的功能
- 常見的裝飾器有:類裝飾器卷中、屬性裝飾器、方法裝飾器皆看、參數(shù)裝飾器
- 裝飾器的寫法:普通裝飾器(無法傳參)仓坞,裝飾器工廠(可傳參)
- 裝飾器是過去幾年中 Js 最大的成就之一背零,已是 ES7 的標準特性之一
類裝飾器
類裝飾器在類聲明之前被聲明(緊靠著類聲明)腰吟。類裝飾器應用于類構造函數(shù),可以用來監(jiān)視徙瓶,修改或替換類定義毛雇。傳入一個參數(shù)
- 普通裝飾器(無法傳參)
function logClass(params: any) { console.log(params) // params 就是當前類 params.prototype.apiUrl = 'xxx' params.prototype.run = function() { console.log("我是一個 run 方法") } } @logClass class HttpClient { constructor() {} getData() {} } let http = new HttpClient() console.log(http.apiUrl) http.run()
- 裝飾器工廠(可傳參)
function logClass(params: string) { return function(target: any) { console.log(target) console.log(params) target.prototype.apiUrl = params } } @logClass('hello') class HttpClient { constructor() {} getData() {} } let http = new HttpClient() console.log(http.apiUrl)
- 類裝飾器:下面是一個重載構造函數(shù)的例子
- 類裝飾器表達式會在運行時當作函數(shù)被調(diào)用,類的構造函數(shù)作為其唯一的參數(shù)
- 如果類裝飾器返回一個值侦镇,它會使用提供的構造函數(shù)來替換類的聲明
function logClass(target: any) { console.log(target) return class extends target { apiUrl: any = '我是修改后的數(shù)據(jù)' getData() { this.apiUrl = this.apiUrl + '----' console.log(this.apiUrl) } } } @logClass class HttpClient { public apiUrl: string | undefined; constructor() { this.apiUrl = "我是構造函數(shù)中的 apiUrl" } getData() { console.log(this.apiUrl); } } let http = new HttpClient() http.getData()
- 屬性裝飾器
- 屬性裝飾器表達式會在運行時當作函數(shù)被調(diào)用灵疮,傳入下列兩個參數(shù):
- 對于靜態(tài)成員來說是類的構造函數(shù),對于實例成員是類的原型對象
- 成員的名字
// 類裝飾器 function logClass(params: string) { return function(target: any) { // console.log(params) // console.log(target) } } // 屬性裝飾器 function logProperty(params: any) { return function(target: any, attr: any) { console.log(params) console.log(target) console.log(attr) target[attr] = params } } @logClass('xxx') class HttpClient { @logProperty('http://itying.com') public url: any | undefined; constructor() { } getData() { console.log(this.url) } } let http = new HttpClient() http.getData()
- 屬性裝飾器表達式會在運行時當作函數(shù)被調(diào)用灵疮,傳入下列兩個參數(shù):
- 方法裝飾器
- 它會被應用到方法的屬性描述符上壳繁,用來監(jiān)視震捣,修改或者替換方法定義。
- 方法裝飾器會在運行時傳入下列3個參數(shù):
- 對于靜態(tài)成員來說是類的構造函數(shù)闹炉,對于實例成員是類的原型對象
- 成員的名字
- 成員的屬性描述符
- 方法裝飾器的使用
- 方法裝飾器一
function get(params: any) { return function(target: any,methodName: any, desc: any) { console.log(target) console.log(methodName) console.log(desc) target.apiUrl = 'xxx' target.run = function () { console.log('run') } } } class HttpClient { public url: any | undefined; constructor() {} @get('http://itying.com') getData() { console.log(this.url) } } let http = new HttpClient() console.log(http.url) http.run()
- 方法裝飾器二
function get(params: any) { return function(target: any,methodName: any, desc: any) { console.log(target) console.log(methodName) console.log(desc.value) // 修改裝飾器的方法 把裝飾器方法里面?zhèn)魅氲乃袇?shù)改為 string 類型 // 1. 保存當前方法 let oMethod = desc.value desc.value = function(...args:any[]) { args = args.map((value) => { return String(value) }) console.log(args) oMethod.apply(this, args) } } } class HttpClient { public url: any | undefined; constructor() {} @get('http://itying.com') getData(...args:any[]) { console.log(args) console.log('getData里面的代碼') } } let http = new HttpClient() http.getData(123, '12333') ```
- 方法裝飾器一
- 方法參數(shù)裝飾器
- 參數(shù)裝飾器表達式會在運行時當作函數(shù)被調(diào)用蒿赢,可以使用參數(shù)裝飾器為類的原型增加一些元素數(shù)據(jù),傳入下列3個參數(shù):
- 對于靜態(tài)成員來說是類的構造函數(shù)渣触,對于實例成員是類的原型對象
- 方法的名稱名字
- 參數(shù)在函數(shù)參數(shù)列表中的索引
function logParams(params: any) { return function(target: any, methodName: any, paramsIndex: any) { console.log(params) console.log(target) console.log(methodName) console.log(paramsIndex) target.apiUrl = params } } class HttpClient { public url: any | undefined; constructor() {} getData(@logParams('uuid') uuid: any) { console.log(uuid) } } let http = new HttpClient() http.getData(123) console.log(http.apiUrl) ```
- 裝飾器執(zhí)行順序
- 屬性 > 方法 > 方法參數(shù) > 類
- 如果有多個同樣的修飾器羡棵,它會先執(zhí)行后面的
function logClass1(params: string) { return function(target: any) { console.log("類裝飾器1") } } function logClass2(params: string) { return function(target: any) { console.log("類裝飾器2") } } function logAttribute(params?: string) { return function(target: any, attrName: any) { console.log("屬性裝飾器") } } function logMethod(params?: string) { return function(target: any, attrName: any, desc: any) { console.log("方法裝飾器") } } function logParams1(params?: string) { return function(target: any, attrName: any, desc: any) { console.log("方法參數(shù)裝飾器1") } } function logParams2(params?: string) { return function(target: any, attrName: any, desc: any) { console.log("方法參數(shù)裝飾器2") } } @logClass1("http://www.itying.com/api") @logClass2("xxxx") class HttpClient { @logAttribute() public apiUrl: string | undefined constructor() { } @logMethod() getData() { return true } setData(@logParams1() attr1:any, @logParams2() attr2:any) {} } let http = new HttpClient() // 輸出順序:屬性裝飾器 方法裝飾器 方法參數(shù)裝飾器2 方法參數(shù)裝飾器2 類裝飾器2 類裝飾器1
- 參數(shù)裝飾器表達式會在運行時當作函數(shù)被調(diào)用蒿赢,可以使用參數(shù)裝飾器為類的原型增加一些元素數(shù)據(jù),傳入下列3個參數(shù):