配置
- tsc --init 生成tsconfig.json
- vscode 任務(wù)-運(yùn)行任務(wù) tsc:監(jiān)視-tsconfig.json
數(shù)據(jù)類型
boolean, number, string, array, null, undefied, void
-
元組類型tuple
let tuple:[number, string] = [1, 's']
-
枚舉類型enum
enum Color { red, blue, yellow = 5, } let color:Color = Color.yellow // 5 color = Color.yellow // 0浪慌, 未賦值則輸出下標(biāo)
任意類型any
null和undefined是其他(never)類型的子類型
void類型: ts中void類型表示沒(méi)有任何類型,一般用于定義方法時(shí)朴则,方法沒(méi)有返回值
never類型:其他類型(null和undefined)的子類型
函數(shù)
// 函數(shù)聲明
function run():string {
return '123'
}
// 匿名表達(dá)式
var run2 = function():string {
return '123'
}
// ts中定義方法傳參
function getInfo(name: string, age: number):string {
return `${name}:${age}`
}
// 方法可選參數(shù)(age可傳权纤,可不傳)
// 可選參數(shù)要放在所有參數(shù)的最后
function getInfo(name: string, age?: number):string {
if (age) {
return `${name}:${age}`
}
return `${name}`
}
// 默認(rèn)參數(shù)
function getInfo(name: string, age: number = 20):string {
if (age) {
return `${name}:${age}`
}
return `${name}`
}
// 剩余參數(shù)
function sum(a: number, b:number, c:number, d:number):number {
return a + b + c + d;
}
可改為
function sum(...res: number[]):number {
return res.reduce((acc, cur) => acc + cur, 0)
}
// ts函數(shù)重載
function getInfo(name: string): string;
function getInfo(age: number): number;
function getInfo(arg: any): any {
return 123;
}
// 箭頭函數(shù)
ts中的類
- 類的定義、繼承
// es5
function Person(name) {
this.name = name;
this.run = function () {
console.log(this.name)
}
}
var p = new Person('張三')
p.run()
// ts中定義類
class Person {
name: string; // 屬性乌妒,省略了public關(guān)鍵詞
constructor(name:string) { // 構(gòu)造函數(shù)汹想,實(shí)例化類時(shí)觸發(fā)的方法
this.name = name;
}
getName():string {
return this.name
}
setName(name: string):void{
this.name = name
}
}
var p = new Person('張三')
p.setName('李四')
alert(p.getName())
// ts中實(shí)現(xiàn)繼承 extends, super
class Person {
name: string; // 屬性,省略了public關(guān)鍵詞
constructor(name:string) { // 構(gòu)造函數(shù)撤蚊,實(shí)例化類時(shí)觸發(fā)的方法
this.name = name;
}
run():string {
return `${this.name} is running`
}
}
class Web extends Person {
constructor(name: string) {
super(name)
}
}
var w = new Web('lisi')
console.log(w.run())
// ts中繼承的探討
class Person {
name: string; // 屬性古掏,省略了public關(guān)鍵詞
constructor(name:string) { // 構(gòu)造函數(shù),實(shí)例化類時(shí)觸發(fā)的方法
this.name = name;
}
run():string {
return `${this.name} is running`
}
}
class Web extends Person {
constructor(name: string) {
super(name)
}
run():string {
return '子類' //父類中也有同名方法侦啸,則調(diào)用子類的方法
}
work() {
alert(`${this.name}在工作`) // this指向web實(shí)例
}
}
var w = new Web('lisi')
console.log(w.run())
類里的修飾符
- ts里定義屬性的時(shí)候槽唾,給我們提供了三種修飾符
/*
public:公有 在類里面,子類和類外面都可以訪問(wèn)
protected:保護(hù)類型 在類里面匹中、子類里面可以訪問(wèn)夏漱,在類外部沒(méi)法訪問(wèn)
private:私有 在類里面可以訪問(wèn),子類和類外部都沒(méi)法訪問(wèn)
*/
// public
// 屬性不加任何修飾符為public
// 類外部訪問(wèn)公有屬性
class Person {
public name: string;
constructor(name:string) {
this.name = name;
}
}
var p = new Person('lala');
console.log(p.name)
// protected
// 在子類中訪問(wèn)
class Person {
protected name: string; // 屬性顶捷,省略了public關(guān)鍵詞
constructor(name:string) { // 構(gòu)造函數(shù)挂绰,實(shí)例化類時(shí)觸發(fā)的方法
this.name = name;
}
}
class Web extends Person {
constructor(name: string) {
super(name)
}
run():string {
return `${this.name}lalalla`
}
}
var w = new Web('ab');
console.log(w.run())
// private 只能在類內(nèi)部訪問(wèn)
class Person {
private name: string; // 屬性,省略了public關(guān)鍵詞
constructor(name:string) { // 構(gòu)造函數(shù),實(shí)例化類時(shí)觸發(fā)的方法
this.name = name;
}
}
靜態(tài)屬性 靜態(tài)方法
- es5
// 實(shí)例方法
function Person() {
this.run1 = function() {
...
}
}
// 靜態(tài)方法
Person.run2 = function() {
}
// 靜態(tài)屬性
Person.name = 'lalal'
var p = new Person();
p.run1()
Person.run2()
-
已經(jīng)有實(shí)例方法葵蒂,為啥要有靜態(tài)方法
// jquery function $(element) { return new Base(element) } function Base (element) { this.element = document.getElementById(element); this.css = function (attr, val) { this.element.style.attr = val } } // 實(shí)例方法 $('#box').css('color', 'red') // 靜態(tài)方法 $.get('url', function() {...})
ts里靜態(tài)方法和屬性
class Person {
public name: string
public age: number = 20
// 靜態(tài)屬性
static sex: string = '男'
constructor(name:string) {
this.name = name;
}
// 實(shí)例方法
run() {
alert(`${this.name}is running`)
}
work() {
alert(`${this.name}is working`)
}
// 靜態(tài)方法 里面沒(méi)法直接調(diào)用類里面的屬性=徊ァ!践付!
static print() {
alert(`print+${Person.sex}`)
}
}
Person.print()
多態(tài) :父類定義一個(gè)方法不去實(shí)現(xiàn)秦士,讓繼承他的子類去實(shí)現(xiàn),每一個(gè)子類有不同的表現(xiàn)
- 多態(tài)屬于繼承
class Animal {
name: string
constructor(name: string) {
this.name = name
}
eat() { // 具體的內(nèi)容永高,讓繼承他的子類去實(shí)現(xiàn)隧土,每個(gè)子類有不同表現(xiàn)
console.log('eat')
}
}
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 + '吃魚'
}
}
var cat = new Cat('cattie')
alert(cat.eat())
ts中的抽象類,提供其他類繼承的基類命爬,不能直接被實(shí)例化
- 用abstract關(guān)鍵字定義抽象類和抽象方法曹傀,抽象類中的抽象方法不包含具體實(shí)現(xiàn)并必須在派生類中實(shí)現(xiàn)
- abstract抽象方法只能放在抽象類里面
- 抽象類和抽象方法用來(lái)定義標(biāo)準(zhǔn)
// Animal類的子類必須包含eat方法
abstract class Animal {
public name: string;
constructor(name:string) {
this.name = name
}
abstract eat():any;
}
// 抽象類的子類必須實(shí)現(xiàn)抽象類里的抽象方法
class Dog extends Animal {
constructor(name:string) {
super(name)
}
eat() {
return this.name + 'something'
}
}
var d = new Dog('abctest+')
alert(d.eat())
ts中的接口
- 定義標(biāo)準(zhǔn)(包括屬性,函數(shù)饲宛,可索引皆愉, 類等)
屬性接口 對(duì)json的約束
// 接口 行為和動(dòng)作的規(guī)范 對(duì)批量方法傳入?yún)?shù)進(jìn)行約束
// 對(duì)傳入對(duì)象的約束, 屬性接口
interface FullName {
firstName: string; // 注意MЭ佟幕庐!分號(hào)結(jié)束
secondName: string;
}
function printName(name: FullName) {
// 必須傳入對(duì)象,必須包含fistName家淤,secondName
console.log(`${name.firstName} ${name.secondName}`)
// console.log(`${name.firstName} ${name.secondName} ${name.age}`) // name.age 報(bào)錯(cuò)
}
// 直接傳入?yún)?shù)异剥,則有且僅有firstName和secondName,否則報(bào)錯(cuò)
// printName({ firstName: 'zhang', secondName: 'san' age: 20 }) // age報(bào)錯(cuò)
// 定義在外面 再傳入媒鼓,則必須包含firstName和secondName届吁,多的參數(shù)也行, 但在方法里調(diào)用fullName不存在的屬性也會(huì)報(bào)錯(cuò)
const obj = {
firstName: 'zhang',
secondName: 'san',
age: 20
}
printName(obj)
- 接口 可選屬性
interface FullName {
firstName: string;
secondName?: string;
}
函數(shù)類型接口: 對(duì)方法傳入的參數(shù),以及返回值進(jìn)行約束 (可批量約束)
interface encrypt {
(key: string, val: string):string
}
var md5:encrypt = function(key: string, val: string):string {
return `${key} + ${val}`
}
console.log(md5('test', '123'))
可索引接口绿鸣,對(duì)數(shù)組/對(duì)象的約束
// 可索引接口 對(duì)數(shù)組的約束
interface UserArr {
[index: number]: string
}
var arrTest: UserArr = ['123', '112']
console.log(arrTest[0])
// 可索引接口 對(duì)對(duì)象的約束
interface UserObj {
[index: string]: string
}
var usrObj:UserObj = {
name: '20'
}
console.log(usrObj.name)
類類型接口
// 類類型接口:對(duì)類的約束 和抽象類有點(diǎn)類似
interface Animal {
name: string;
eat(str: String):void;
}
class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
// 必須有eat方法疚沐,eat方法可不傳參數(shù)
eat() {
console.log(this.name + '吃糧食')
}
}
var d = new Dog('xxiaohei')
d.eat()
class Cat implements Animal {
name: string;
constructor(name: string) {
this.name = name
}
eat(food: string) {
console.log(`${this.name} + ${food}`)
}
}
var c = new Cat('miaomiao')
c.eat('laoshu')
接口的擴(kuò)展、接口的繼承(接口可以繼承接口)
// 例子一
interface Animal {
eat():void
}
interface Person extends Animal {
work():void
}
class Web implements Person {
public name: string;
constructor(name:string) {
this.name = name
}
eat() {
console.log(`${this.name} --- chi`)
}
work() {
console.log(`${this.name} --- work`)
}
}
var ww = new Web('webbbb')
ww.eat()
ww.work()
// 例子二 繼承 + 實(shí)現(xiàn)(接口擴(kuò)展)
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} + coding... + ${code}`)
}
}
class Web extends Programmer implements Person {
constructor(name:string) {
super(name)
}
eat() {
console.log(`${this.name} --- chi`)
}
work() {
console.log(`${this.name} --- work`)
}
}
var ww = new Web('webbbb')
ww.eat()
ww.work()
ww.coding('ts')
泛型
- 解決類 潮模,接口亮蛔,方法的復(fù)用性, 以及對(duì)不特定數(shù)據(jù)類型的支持
- 泛型可以支持不特定的類型數(shù)據(jù),要求:傳入的參數(shù)和返回的參數(shù)一致
泛型的定義擎厢,泛型函數(shù)
// T表示泛型 具體什么類型是調(diào)用這個(gè)方法的時(shí)候決定的
function getData<T>(value:T):T {
return value
}
// function getData<T>(value:T):any {
// return 'test'
// }
// getData<Number>('test'); 錯(cuò)誤寫法
getData<Number>(123); // 參數(shù)必須是number
泛型類
// 最小堆算法究流,需要同時(shí)支持返回?cái)?shù)字和字符串兩種類型,通過(guò)類的泛型來(lái)實(shí)現(xiàn)
class MinClass<T> {
public list: T[] = []
add(num:T) {
this.list.push(num)
}
min():T {
var minNum = this.list[0]
for (let i = 0; i < this.list.length; i++) {
if (this.list[i] < minNum) {
minNum = this.list[i]
}
}
return minNum
}
}
var m = new MinClass<number>() // 實(shí)例化類动遭,且制定T代表number
m.add(2)
m.add(3)
m.add(4)
alert(m.min())
var m2 = new MinClass<string>()
m2.add('44')
m2.add('a')
m2.add('v')
alert(m2.min())
泛型接口
// 1. 第一種定義泛型接口的方法
interface ConfigFn {
<T>(val:T):T
}
var getData:ConfigFn = function<T>(value: T) {
return value
}
getData<string>('123')
// 2.第二種定義泛型接口的方法
interface ConfigFn<T> {
(val:T):T;
}
function getData<T>(value: T):T {
return value
}
var myGetData:ConfigFn<string> = getData;
myGetData('20')
把類作為參數(shù)類型的泛型類
- 先定義個(gè)類
- 把類作為參數(shù)來(lái)約束數(shù)據(jù)傳入的類型
功能一
class User {
username: string | undefined;
password: string | undefined;
}
class MysqlDb {
add(user: User): boolean {
console.log(user)
return true
}
}
var u = new User()
u.username = 'zhangsan'
u.password = '123456'
var db = new MysqlDb()
db.add(u)
功能二
class ArticleCate {
title: string | undefined;
desc: string | undefined;
status: number | undefined;
}
class MysqlDb {
add(info: ArticleCate): boolean {
console.log(info)
return true
}
}
var a = new ArticleCate()
a.title = '國(guó)內(nèi)'
a.desc = '國(guó)內(nèi)新聞'
a.status = 1
var DB = new MysqlDb()
DB.add(a)
但mySqlDb重復(fù)封裝了芬探,通過(guò)泛型解決
// 操作數(shù)據(jù)庫(kù)的泛型類
class MysqlDb <T> {
add(info: T): boolean {
console.log(info)
return true
}
update(info: T, id: number):boolean {
console.log(info)
console.log(id)
return true
}
}
// 1.定義一個(gè)user類和數(shù)據(jù)庫(kù)進(jìn)行映射
class User {
username: string | undefined;
password: string | undefined;
}
var u = new User()
u.username = 'zhangsan'
u.password = '123456'
var DB = new MysqlDb<User>()
DB.add(u)
// 1.定義一個(gè)ArticleCate類和數(shù)據(jù)庫(kù)進(jìn)行映射
class ArticleCate {
title: string | undefined;
desc: string | undefined;
status: number | undefined;
constructor(params: {
title?: string,
desc?: string,
status?: number ,
}) {
this.title = params.title
this.desc = params.desc
this.status = params.status
}
}
var a = new ArticleCate({
title: '分類',
desc: '111'
})
var DB2 = new MysqlDb<ArticleCate>()
DB2.add(a)
DB2.update(a, 2)
ts類型,接口厘惦,類偷仿,泛型綜合使用
interface DBI<T> {
add(info: T):boolean;
update(info: T, id: number):boolean;
delete():boolean;
get(id: number): any[]
}
// 定義一個(gè)操作mySql數(shù)據(jù)庫(kù)的類 注意:要實(shí)現(xiàn)泛型接口,這個(gè)類也應(yīng)該是一個(gè)泛型類
class MysqlDb<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(): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
var list = [
{
title: 'xxxx',
desc: 'xxx1'
},
{
title: 'xxxx',
desc: 'xxx1'
},
]
return list
}
}
// 定義一個(gè)操作mySql數(shù)據(jù)庫(kù)的類 注意:要實(shí)現(xiàn)泛型接口,這個(gè)類也應(yīng)該是一個(gè)泛型類
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(): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
var list = [
{
title: 'xxxx',
desc: 'xxx1'
},
{
title: 'xxxx',
desc: 'xxx1'
},
]
return list
}
}
// 操作用戶表 定義一個(gè)user類和數(shù)據(jù)表的映射
class User {
username: string | undefined;
password: string | undefined;
}
var u = new User()
u.username = 'zhangsan'
u.password = '123456'
var oMySql = new MysqlDb<User>(); // 用類約束傳入?yún)?shù)的合法性
oMySql.add(u)
console.log(oMySql.get(4))
var oMsSql = new MssqlDb<User>()
oMsSql.add(u)
console.log(oMsSql.get(1))
ts 模塊化封裝
模塊的定義酝静,引用
// db.ts
var dbUrl = 'xxx'
function getData():any[] {
console.log('獲取數(shù)據(jù)庫(kù)數(shù)據(jù)')
var list = [
{
title: '222'
}, {
title: '333'
}
]
return list
}
function saveData() {
console.log('保存')
}
export {
dbUrl,
getData,
saveData
}
// export default getData // export default在一個(gè)模塊中只能用一次节榜,引入時(shí)import getData from ’xxxx/xxx‘
// index.ts
import { getData as get, saveData } from './modules/db'
get()
saveData()
應(yīng)用舉例:封裝db庫(kù)
// modules/db.ts
interface DBI<T> {
add(info: T):boolean;
update(info: T, id: number):boolean;
delete():boolean;
get(id: number): any[]
}
export 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(): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
var list = [
{
title: 'xxxx',
desc: 'xxx1'
},
{
title: 'xxxx',
desc: 'xxx1'
},
]
return list
}
}
// model/user.ts
import { MssqlDb } from '../modules/db'
class UserClass {
username: string | undefined;
password: string | undefined;
}
var UserModel = new MssqlDb<UserClass>(); // 用類約束傳入?yún)?shù)的合法性
export {
UserClass,
UserModel
}
// index.ts
import { UserClass, UserModel } from './model/user'
import {ArticleClass, ArticleModel } from './model/article'
var user = new UserClass();
user.username = 'zhangsan'
user.password = '123344'
UserModel.add(user)
var res = UserModel.get(123)
console.log(res)
命名空間 命名空間塊化
namespace A {
// ...
}
namespace B {
// ...
export class Dog {
name: string;
constructor(name:string) {
this.name = name
}
}
}
// 調(diào)用命名空間中的方法,或類别智,需要在namespace中暴露export出來(lái)
var d = new B.Dog('jfsldjf')
console.log(d)
可將命名空間當(dāng)作一個(gè)模塊直接暴露出來(lái)
// modules/a.ts
export namespace A {
// ...
}
// index.ts
import { A } from 'xxxx'
var d = new A.dog('test')
命名空間和模塊的區(qū)別:命名空間主要用于組織代碼宗苍,避免命名沖突;模塊側(cè)重代碼的重用薄榛,一個(gè)模塊可能會(huì)有多個(gè)命名空間
裝飾器
裝飾器:是一種特殊類型的聲明讳窟,能夠被附加到類聲明,方法蛇数,屬性挪钓,或參數(shù)上是越,可以修改類的行為
通俗的講耳舅,裝飾器就是一個(gè)方法,可以注入到類倚评,方法浦徊,屬性參數(shù)上來(lái)擴(kuò)展類,屬性天梧,方法盔性,參數(shù)的功能;
常見(jiàn)裝飾器有:類裝飾器呢岗,屬性裝飾器冕香,方法裝飾器,參數(shù)裝飾器
裝飾器的寫法:普通裝飾器(無(wú)法傳參)后豫;裝飾器工廠(可傳參)
類裝飾器
普通裝飾器(無(wú)法傳參)
// 類裝飾器悉尾,在類聲明之前被聲明(緊接著類聲明),應(yīng)用于類構(gòu)造函數(shù)挫酿,可用來(lái)監(jiān)視构眯、修改、或替換類定義
// 裝飾器
function logClass(params:any) {
console.log(params) // params 就是當(dāng)前類
params.prototype.apiUrl = 'xxxx'
params.prototype.run = function() {
console.log('run method')
}
}
@logClass
class HttpClient {
constructor() {
}
getData() {
}
}
var http: any = new HttpClient()
console.log(http.apiUrl)
http.run()
裝飾器工廠(可傳參數(shù))
// 裝飾器工廠
function logClass(params: string) {
return function(target: any) { // target為類
// console.log(target, params)
target.prototype.apiUrl = params
}
}
@logClass('http://hello')
class HttpClient {
constructor() {
}
getData() {
}
}
var http:any = new HttpClient()
console.log(http.apiUrl)
類裝飾器:下面是一個(gè)重載構(gòu)造函數(shù)的例子, (修改當(dāng)前類的構(gòu)造函數(shù)或方法早龟,可看為固定用法)
function logClass(target:any) {
console.log(target)
return class extends target {
apiUrl: any = '修改后數(shù)據(jù)'
getData() {
console.log(`${this.apiUrl} + 修改后的`)
}
}
}
@logClass
class HttpClient {
public apiUrl: string | undefined;
constructor() {
this.apiUrl = '我是構(gòu)造函數(shù)里面的apiUrl'
}
getData() {
console.log(this.apiUrl)
}
}
var http = new HttpClient()
http.getData()
屬性裝飾器
// 屬性裝飾器
// 屬性裝飾器表達(dá)式會(huì)在運(yùn)行時(shí)當(dāng)作函數(shù)被調(diào)用惫霸,傳入下列2個(gè)參數(shù)
// 1. 對(duì)靜態(tài)成員來(lái)說(shuō)是類的構(gòu)造函數(shù),對(duì)實(shí)例成員來(lái)說(shuō)是類的原型對(duì)象
// 2. 成員的名字
function logProperty(params:any) {
return function (target:any, attr: any) {
console.log(target, attr)
target[attr] = params
}
}
@logClass('http://hello')
class HttpClient {
@logProperty('newUrl')
public url: any | undefined
constructor() {
}
getData() {
console.log('getData===>', this.url)
}
}
var http = new HttpClient()
http.getData()
方法裝飾器
方法裝飾器 會(huì)應(yīng)用到方法的屬性描述符上葱弟,可以用來(lái)監(jiān)視壹店,修改,或者替換方法定義
方法裝飾器會(huì)在運(yùn)行時(shí)芝加,傳入下列三個(gè)參數(shù)
1. 對(duì)于靜態(tài)成員來(lái)說(shuō)是類的構(gòu)造函數(shù)硅卢,對(duì)于實(shí)例成員是類的原型對(duì)象
2. 成員的名字
3. 成員的屬性描述符
方法裝飾器一: 修改當(dāng)前實(shí)例的屬性和方法
function get(params:any) {
return function(target:any, methodName: any, desc:any) {
console.log(target, methodName, desc) // 仍可改變類原型上的方法和屬性
target.apiUrl = 'apiUro'
target.run = function() {
console.log('run')
}
}
}
class HttpClient {
public url: any | undefined
constructor() {
}
@get('htttp://dksjflsjkf')
getData() {
console.log('getData===>', this.url)
}
}
var http:any = new HttpClient()
console.log(http.apiUrl)
http.run()
方法裝飾器二: 修改當(dāng)前方法
function get(params:any) {
return function(target:any, methodName: any, desc:any) {
console.log(target, methodName, desc.value)
// 修改裝飾器的方法,把裝飾器方法里面?zhèn)魅氲乃袇?shù)改為string類型
// 1. 保存當(dāng)前方法
var oMethod = desc.value;
desc.value = function(...args: any[]) {
args = args.map(val => String(val))
console.log(args)
// 2. 調(diào)用原來(lái)的舊方法(看是否需要直接覆蓋,可省略)
oMethod.apply(this, args)
}
}
}
class HttpClient {
public url: any | undefined
constructor() {
}
@get('htttp://dksjflsjkf')
getData(...args:any[]) {
console.log('我是getData', args)
}
}
var http:any = new HttpClient()
http.getData(123, 'xdd')
方法參數(shù)裝飾器
參數(shù)裝飾器表達(dá)式會(huì)在運(yùn)行時(shí)當(dāng)作函數(shù)被調(diào)用老赤,可用使用參數(shù)裝飾器為類的原型增加一些元素?cái)?shù)據(jù)轮洋,傳入下列3個(gè)參數(shù)
1. 對(duì)于靜態(tài)成員來(lái)說(shuō)是類的構(gòu)造函數(shù),對(duì)于實(shí)例成員是類的原型對(duì)象
2. 方法的名字
3. 參數(shù)在函數(shù)參數(shù)列表中的索引
function logParam(params: any) {
return function(target:any, methodName: any, paramsIndex:any) {
// console.log(params)
// console.log(target, methodName, paramsIndex)
target.apiUrl = params
}
}
class HttpClient {
public url: any | undefined
constructor() {
}
getData(@logParam('uuid') uuid:any) {
// console.log(uuid)
}
}
var http:any = new HttpClient()
console.log(http.apiUrl)
http.getData(123456)
裝飾器的執(zhí)行順序
- 屬性 > 方法 > 方法參數(shù) > 類裝飾器
- 有多個(gè)同樣的裝飾器抬旺,則會(huì)先執(zhí)行后面的
function logClass1(params:string) {
return function(target:any) {
console.log('類裝飾器1')
}
}
function logClass2(params:string) {
return function(target:any) {
console.log('類裝飾器2')
}
}
function logAttr(params?:string) {
return function(target:any, attr: any) {
console.log('屬性裝飾器')
}
}
function logMethod(params?:string) {
return function(target:any, methodName: any, desc: any) {
console.log('方法裝飾器')
}
}
function logParam1(params?: any) {
return function(target:any, methodName: any, paramsIndex:any) {
console.log('方法參數(shù)裝飾器1')
}
}
function logParam2(params?: any) {
return function(target:any, methodName: any, paramsIndex:any) {
console.log('方法參數(shù)裝飾器2')
}
}
@logClass1('http://1')
@logClass2('http://2')
class HttpClient {
@logAttr()
public url: any | undefined
constructor() {
}
@logMethod()
getData() {
return true
}
setData(@logParam1() attr1:any, @logParam2() attr2: any) {
}
}
var http:any = new HttpClient()
// 打印結(jié)果是
/ *
屬性裝飾器
方法裝飾器
方法參數(shù)裝飾器2
方法參數(shù)裝飾器1
類裝飾器2
類裝飾器1
*/