<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Typescript詳解

      1. typescript由微軟開發的一款開源編程語言。
      2. ts是jacascript的超集,遵循ES6,ES5規范,ts擴展了js的語法。
      3. ts更像后端java,c#這樣的面向對象的語言,可以讓js開發大型的企業項目,
      4. 谷歌也大力支持ts的推廣,谷歌的angular2.x就是基于ts語法開發的
      5. 最新的Vue,React也繼承ts
      6. Nodejs框架Nestjs,midway中用的就是ts語法.

      基礎配置

      安裝:npm i -g typescript
      驗證是否安裝成功:tsc -v
      Version 4.4.3
      編譯ts:tsc index.ts(需要編譯的ts文件)

      ts開發工具 vscode自動編譯ts

      1. 創建tsconfig.json文件

        tsc --init 生成配置文件
        只改tsconfig:outdir:'./js'

      2. 自動生成js

        vscode-->終端-->運行任務-->typescript-->tsc:監視

      一、ts中的類型

      ts中為了是編寫的代碼更加規范,更有利于維護,增加了類型校驗。
      類型賦值錯誤會報錯,
      主要類型有:

      類型 名稱 解釋 寫法
      布爾類型 boolean true/false var flag:boolean=true
      數值類型 number 整數/小數 var num:number=123
      字符串類型 string 字符串 var str:string='123'
      數組類型 array 數組 let arr:number[]=[1,2,3](只能放number類型)/let arr:Array=[1,2,3](只能放number類型,泛型定義)/
      元組類型 tuple 數組的一種可以指定數組里每項類型 let arr:[string,number,boolean]=['ww',123,true]
      枚舉類型 enum enum 枚舉名稱 enum Flag{success:1,err:-1},var f:Flag=Flag.err
      enum Color={red,blue,orage} ,var c:Color=Color.blue //c==1
      任意類型 any 任意的值 let num:any='123'
      null、undefined 其他類型子類型 var num:number
      void類型 void 沒有任何類型,一般用于函數沒有返回值 function run():void {}
      其他類型 never 包括null,undefined子類型,代表從不會出現的值 never的變量只能被never類型賦值

      二、函數定義

      ES5函數定義

      函數聲明

      function run() {
          return 'run'
      }
      

      匿名函數

      var run2 = function () { }
      

      ts函數定義方法

      1-函數聲明

      function run1(): string {
          return 'aa'
      }
      

      2-匿名函數

      var fun2 = function (): number {
          return 123
      }
      

      3-傳參

      function getInfo(name: string, age: number): string {
          return `${name}++${age}`
      }
      console.log(getInfo('asd', 22))
      

      4-無返回值
      ```function run3(): void { }````

      ts方法的可選參數

      ES5方法的實參和形參可以不一樣,ts中必須一樣,如果不一樣需要配置可選參數
      注意:可選參數必須配置到參數最后面,用?表示可選

      function getInfos(name: string, age?: number): string {
          return `${name}++${age}`
      }
      

      默認參數

      es5里面沒法設置默認參數,es6和ts找那個可以設置默認參數
      默認參數可以不傳,類似于可選參數

      function getInfo1(name: string, age: number = 20): string {
          return `${name}++${age}`
      }
      

      剩余參數

      1-改進前寫法

      function sum(a: number, b: number, c: number, d: number): number {
          return a + b + c + d
      }
      

      2-改進后
      三點運算符 接收新傳過來的值

      function sum1(...arr: number[]): number {
          var sum = 0
          for (let i = 0; i < arr.length; i++) {
              sum += arr[i]
          }
          return sum
      }
      alert(sum1(1, 2, 3, 4))
      

      另一種

      function sum2(a: number, ...arr: number[]): number {
          var sum = 0
          for (let i = 0; i < arr.length; i++) {
              sum += arr[i]
          }
          return a + sum
      }
      alert(sum2(1, 2, 3, 4))
      

      函數重載

      java中方法的重載,:兩個或以上同名函數,但他們參數不一樣,這是會出現函數重載情況
      ts中的從在,通過為一個函數提供多個函數類型定義來實現多種功能的目的
      ts為了箭筒es5和es6從在寫法和java中有區別
      es5中出現同名方法,下面的會替換上面的方法
      ts重載

      function getcon(name: string): string;
      function getcon(age: number): number;
      function getcon(name: string,age: number): string;
      
      function getcon(str: any,age?:number): any {
          if (typeof str == 'string') {
              return '姓名' + str
          } else {
              return '年齡' + str
          }
      }
      

      三、對象的繼承

      es5繼承

      1. es5里面的構造函數

        function Person() {
            this.name = '張珊'
            this.age = 20
            this.run = function () {
            }
        }
        
      2. 原型鏈上的屬性會被多個實例共享,構造函數不會

        function Person() {
            this.name = '張珊'
            this.age = 20
            this.run = function () {
            }
        }
        Person.prototype.sex = '男'
        Person.prototype.work = function () {
            console.log(this.name)
        }
        Person.getInfo = function () {
            // 靜態方法
        }
        var p = new Person()
        p.work()
        // 調用靜態方法
        Person.getInfo()
        
      3. 構造函數與原型鏈增加方法

        function Person() {
            this.name = '張珊'
            this.age = 20
            this.run = function () {
        
            }
        }
        // 原型鏈上的屬性會被多個實例共享,構造函數不會
        Person.prototype.sex = '男'
        Person.prototype.work = function () {
            console.log(this.name)
        }
        Person.getInfo = function () {
            // 靜態方法
        }
        var p = new Person()
        p.work()
        
      4. 類里面的靜態方法

        function Person() {
            this.name = '張珊'
            this.age = 20
        }
        // 定義靜態方法
        Person.getInfo = function () {
        }
        var p = new Person()
        // 調用靜態方法
        Person.getInfo()
        
      5. es5繼承
        原型鏈+對象冒充

        function Person(age) {
            this.name = '張珊'
            this.age = age
        }
        Person.prototype.sex = '男'
        Person.prototype.work = function () {
            console.log(this.name)
        }
        var p = new Person(18)
        // 對象冒充繼承---不可以繼承原型鏈的屬性和方法
        function Web(){
            Person.call(this)
        }
        
        // 原型鏈繼承-----實例化后沒法給父類傳參
        Web.prototype=new Person()
        var son=new Web()
        

      ts繼承

      1、ts定義類

      class Person {
          name: string; //屬性 省略了public關鍵詞
          constructor(n: string) {
              this.name = n
          }//構造函數,實例化類的時候觸發的方法
          run(): void { }
      }
      var p = new Person('aa')
      p.run()
      

      2、ts中實現繼承

      關鍵字:extends,super
      子類與父類有相同方法,子類優先級更高

      class Person1 {
          name: string; //屬性 省略了public關鍵詞
          constructor(n: string) {
              this.name = n
          }//構造函數,實例化類的時候觸發的方法
          run(): string {
              return `${this.name}是`
          }
      }
      class Webs extends Person1 {
          constructor(name: string) {
              super(name)//類似于初始化父類構造函數
          }
          work() { }
      }
      var w = new Webs('李四')
      

      3、ts類里面的修飾符

      ts里面定義屬性的時候給我們提供了三種修飾符

      • public :公有:在類里面,子類,類外面都可以訪問

      • protected :保護類型:在類里面,子類都可以訪問,類外面不可以訪問

      • private:私有:在類里面可以訪問,子類,類外面都不可以訪問

      • 屬性不加修飾符默認公有public

      class Person2 {
          name: string; //屬性 省略了public關鍵詞
          private age: number
          constructor(n: string, a: number) {
              this.name = n
              this.age = a
          }//構造函數,實例化類的時候觸發的方法
          run(): string {
              return `${this.name}是`
          }
      }
      

      4、靜態屬性 靜態方法

      es5里面的

      function Person(){}
      Person.run2=function(){}//靜態方法
      

      ts里面的
      靜態方法無法調用類里面的屬性,可以調用靜態屬性

      class Person3 {
          static sex = 'nam'//靜態屬性
          public name: string
          constructor(name: string) {
              this.name = name
          }
          run() { }
          static prient() {console.log(this.sex,Person3.sex) }//靜態方法
      }
      var p = new Person3('11')
      Person3.prient()//靜態方法調用
      

      5、多態

      父類定義一個方法不去實現,讓繼承它的子類去實現,每個子類有不同的表現
      多態屬于繼承的一種表現

      class Animal{
          name:string
          constructor(name:string){
              this.name=name
          }
          eat(){
              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+'吃魚'
          }
      }
      

      6、抽象方法

      • ts中的抽象類,他提供其他類集成的基類,不能直接被實例化
      • 用abstract關鍵字定義抽象類和抽象方法,抽象類中的抽象方法不包含具體實現并且必須在派生類中實現
      • abstract抽象方法只能放在抽象類里面
      • 抽象類的子類必須事項抽象類里面的方法

      抽象類和抽象方法用來定義標準
      標準:Animal這個類要求他的子類必須包含eat

      abstract class Animals{
          /**
           * name
           */
          public name:string
          constructor(name:string){
              this.name=name
          }
          abstract eat():any;
      }
      // 抽象類的子類必須事項抽象類里面的方法
      class Dogs extends Animal{
          constructor(name:string){
              super(name)
          }
          eat(){
              return this.name+'吃肉'
          }
      }
      

      四、接口

      接口的作用:在面向對象的編程中,接口是一種規范的定義,它定義了行為和動作的規范,在程序設計里面,換口起到一種限制和規范的作用。接口定義了某一批央所雷要遵守的現范,接口不關心這些類的內部狀態數據,也不關心這些類里方法的實現細節,它只規定這批類里必須提供某些方法,提供這些方法的類就可以滿足實際需要。typescrip中的接口類似于java,同時還增加了更靈活的接口類型,包括屬性面數、可索引和類

      1.屬性接口

      1、對json的約束

      ts自定義方法傳入對json進行約束

      function prientLabel(labelInfo: { label: string }): void {
      
      }
      prientLabel({ name: 'aa' })//錯誤寫法
      prientLabel({ label: 'aa' })//正確寫法
      

      2、對批量方法進行約束

      接口:行為和動作規范,對批量方法進行約束
      參數順序可以不一樣,但必須得有
      關鍵詞:interface

      interface FullName {
          firstName: string;//注意;結束
          secondName: string;
      }
      function prientName(name: FullName) {
          // 必須傳入對象 firstName secoendName
          console.log(name.firstName, name.secondName)
      }
      var obj = { firstName: '1', secondName: 'jj', age: 1 }
      prientName(obj)
      prientName({ firstName: '1', secondName: 'jj', age: 1 })//傳age有問題
      

      接口:可選屬性

      interface FullNames {
          firstName: string;//注意;結束
          secondName?: string;
      }
      

      案例

      interface Config {
          type: string;
          url: string;
          data?: string
          dataType: string
      }
      function ajax(config: Config) {
          var xhr = new XMLHttpRequest()
          xhr.open(config.type, config.url, true)
          xhr.send(config.data)
          xhr.onreadystatechange = function () {
              if (xhr.readyState == 4 && xhr.status == 200) {
                  if (config.dataType == 'json') {
                      JSON.parse(xhr.response)
                  }
              }
          }
      }
      ajax({
          type: 'get',
          url: 'http://..',
          data: '',
          dataType: 'json'
      })
      

      2.函數類型接口

      對傳入的參數以及返回值進行約束
      加密函數類型接口

      interface encrypt {
          (ke: string, value: string): string
      }
      var md5: encrypt = function (key: string, value: string): string {
          return key + value
      }
      

      3.可索引接口

      數組,對象的約束(不常用)

      interface UserArr {
          [index: number]: string
      }
      var arr: UserArr = ['11', '22']
      interface UserObj {
          [index: string]: string
      }
      var objw: UserObj = { name: '20' }
      

      4.類類型接口

      對類進行約束和抽象類有點相似
      關鍵字:implements

      interface Animal1 {
          name: string;
          eat(str: string): void
      }
      class Dog implements Animal1 {
          name: string;
          constructor(name: string) {
              this.name = name
          }
          eat() {
          }
      }
      

      5.接口擴展

      接口可以繼承接口

      interface Animalss {
          eat(): void
      }
      interface Person extends Animalss {
          work(): void
      }
      class Son implements Person {
          name: string
          constructor(name: string) {
              this.name = name
          }
          eat() { }
          work() { }
      }
      
      
      class Progeammer {
          name: string
          constructor(name: string) {
              this.name = name
          }
          coding() { }
      }
      class web extends Progeammer implements Person {
          constructor(name: string) {
              super(name)
          }
          eat() { }
          work() { }
          coding() { }
      }
      

      五、泛型

      • 泛型,軟件工程中,我們不僅要創建一致的定義良好的API,同時也要考慮可重用性。 組件不僅能夠支持當前的數據類型,同時也能支持未來的數據類型,這在創建大型系統時為你提供了十分靈活的功能。
      • 在像C#和Java這樣的語言中,可以使用泛型來創建可重用的組件,一個組件可以支持多種類型的數據。這樣用戶就可以以自己的數據類型來使用組件。
      • 通俗理解:泛型就是解決類 接日 方法的復用性、以及對不特定數據類型的支持
        普通寫法
        只能返回string類型的數據
      function getData(value:string):string{return value}
      

      返回多種類型的數據 any可以解決這種問題(any放棄了類型檢查)

      function getData1(value:any):any{return value}
      

      1.泛型定義

      1. 傳入和返回類型相同
      2. 可以支持不特定的數據類型
      3. T表示泛型,具體什么類型是調用這個方法的時候決定的
        function getData2<T>(value:T):T{return value}
        getData2<number>(123)
        // getData2<number>(‘kkk’)/* 錯誤寫法 */
        

      2.泛型類

      普通寫法

      class Minclass{
          public list:number[]=[]
          add(num:number){
              this.list.push(num)
          }
          min():number{
              var min=this.list[0]
              for (let i = 0; i < this.list.length; i++) {
                 if(min>this.list[i]){
                     min=this.list[i]
                 }
                  
              }
              return min
          }
      }
      

      泛型類寫法

      class Minclass1<T>{
          public list:T[]=[]
          add(num:T):void{
              this.list.push(num)
          }
          min():T{
              var min=this.list[0]
              for (let i = 0; i < this.list.length; i++) {
                 if(min>this.list[i]){
                     min=this.list[i]
                 }
                  
              }
              return min
          }
      }
      var m1=new Minclass1<number>()
      

      3.泛型接口

      interface ConfigFn{
          (value:string,value2:string):string
      }
      var setData:ConfigFn=function(val:string,val2:string):string{
          return val+val2
      }
      
      interface ConfigFn1{
          <T>(value:T,value2:T):T
      }
      var setData1:ConfigFn1=function<T>(val:T,val2:T):T{
          return val
      }
      setData1<string>('123','11')
      
      interface ConfigFn2<T>{
          (value:T):T
      }
      function getData6<T>(val:T):T{
          return val
      }
      var myGetData:ConfigFn2<string>=getData6
      myGetData('ll')
      

      案例

      class User{
          name:string|undefined;
          pass:string|undefined
      }
      class Mysql{
          add(user:User):boolean{
              return true
          }
      }
      var u=new User()
      u.name='zhang'
      u.pass='123'
      
      var db=new Mysql()
      db.add(u)
      

      泛型封裝

      class User1{
          name:string|undefined;
          pass:string|undefined
      }
      class Mysql1<T>{
          add(info:T):boolean{
              return true
          }
      }
      var u=new User1()
      u.name='zhang'
      u.pass='123'
      var db1=new Mysql1<User1>()
      db1.add(u)
      

      案例

      功能:定義一個操作數據庫的庫支持 Mysql MssqlMongoDb
      要求1:Mysql MsSqlMongoDb功能一樣都有 add update delete get方法
      注意:約束統一的規范、以及代碼重用
      解決方案:需要約束規范所以要定義接口,需要代碼重用所以用到泛型
      1、接口:在面向對象的編程中,接口是一種規范的定義,它定義了行為和動作的規范
      2、泛型 通俗理解:泛型就是解決類 接口 方法的復用性、

      interface DBI<T>{
          add(info:T):boolean;
          update(info:T,id:number):boolean
          delete(id:number):boolean
          get(id:number):any[]
      }
      // 定義一個操作mysql數據庫的類
      class MysqlDb<T> implements DBI<T>{
          add(info: any): boolean {
              throw new Error("Method not implemented.")
          }
          update(info: any, 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類和數據庫映射表
      class Users{
          name:string|undefined
          pass:string|undefined
      }
      var u=new Users()
      u.name='00'
      u.pass='ii'
      var omysql=new MysqlDb<Users>()
      omysql.add(u)
      

      六、模塊

      • 模塊的的概念(官方):
        1. 關于木語的一點說明:請務必注意一點,TypeScript 1.5里木語名已經發生了變化。“內部模塊”現在稱做“命名空間”。外部模塊“現在則簡稱為“模塊#模塊在且自身的作用域里執行,而不是在全局作用域里:
        2. 這意味著定義在一個模塊里的變量,因數,類等等在模塊外部是不可見的,除非你明確地使用export形式之一導出它們。相反,如果想使用其它模塊導出的變量,國數,類,接口等的時候,你必須要導入它們,可以使用 import形式之一。
      • 模塊的概念(自己理解):
        1. 我們可以把一些公共的功能單獨抽離成一個文件作為一個模塊。
        2. 模塊里面的變量 函數 類等默認是私有的,如果我們要在外部訪問模塊里面的數據(變量、函數、類),我們要要通過export暴露模塊里面的數據(變量、團數、類。。》。
        3. 暴露后我們通過 import 引入模塊就可以使用模塊里面暴露的數據(變量、函數、類...)。

      自定義模塊

      var dburl='xxx'
      export function getData():any[]{
          return[{
              title:'123'
          },{
              title:'456'
          }]
      }
      

      導入

      import {getData} from './db'
      getData()
      

      export default 默認導出
      每個模塊都可以有一個default導出,默認導出使用default關鍵字標記;并且一個模塊只能夠有一個default導出,需要使用一個特殊的導入形式

      七、命名空間

      • 在代碼量較大的情況下,為了避免各種變量命名相沖突,可將相似功能的函數、類、接口等放置到命名空間內
      • 同Java的包、.Net的命名空間一樣,TypeScript的命名空間可以將代碼包裹起來,只對外暴露需要在外部訪問的對象。命名空間內的對象通過export關鍵字對外暴露。

      命名空間和模塊的區別

      • 命名空間:內部模塊,主要用于組織代碼,避免命名沖突。
      • 模 塊:ts的外部模塊的簡稱,側重代碼的復用,一個模塊里可能會有多個命名空間。
      namespace A{
          interface Animal {
              name: string;
              eat(): void;
          }
          export class Dog implements Animal {
              name: string;
              constructor(theName: string) {
                  this.name = theName;
              }
      
              eat() {
                  console.log(`${this.name} 在吃狗糧。`);
              }
          }
      
          export class Cat implements Animal {
              name: string;
              constructor(theName: string) {
                  this.name = theName;
              }
      
              eat() {
                  console.log(`${this.name} 吃貓糧。`);
              }
          }   
      
      }
      
      namespace B{
          interface Animal {
              name: string;
              eat(): void;
          }
          export class Dog implements Animal {
              name: string;
              constructor(theName: string) {
                  this.name = theName;
              }
      
              eat() {
                  console.log(`${this.name} 在吃狗糧。`);
              }
          }
      
          export class Cat implements Animal {
              name: string;
              constructor(theName: string) {
                  this.name = theName;
              }
      
              eat() {
                  console.log(`${this.name} 在吃貓糧。`);
              }
          }   
      
      }
      
      var c=new B.Cat('小花');
      
      c.eat();
      

      封裝:模塊化+命名空間

      export namespace A{
          interface Animal {
              name: string;
              eat(): void;
          }
          export class Dog implements Animal {
              name: string;
              constructor(theName: string) {
                  this.name = theName;
              }
      
              eat() {
                  console.log(`${this.name} 在吃狗糧。`);
              }
          }
      
          export class Cat implements Animal {
              name: string;
              constructor(theName: string) {
                  this.name = theName;
              }
      
              eat() {
                  console.log(`${this.name} 吃貓糧。`);
              }
          }   
      
      }
      
      import {A} from './modules/animal';
      var d=new A.Dog('小黑');
      d.eat();
      

      八、裝飾器

      屬性裝飾器
      裝飾器工廠

      裝飾器定義

      • 裝飾器:裝飾器是一種特殊類型的聲明,它能夠被附加到類聲明,方法,屬性或參數上,可以修改類的行為。
      • 通俗的講裝飾器就是一個方法,可以注入到類、方法、屬性參數上來擴展類、屬性、方法、參數的功能。
      • 常見的裝飾器有:類裝飾器、屬性裝飾器、方法裝飾器、參數裝飾器
      • 裝飾器的寫法:普通裝飾器(無法傳參) 、 裝飾器工廠(可傳參)
      • 裝飾器是過去幾年中js最大的成就之一,已是Es7的標準特性之一

      類裝飾器

      類裝飾器:類裝飾器在類聲明之前被聲明(緊靠著類聲明)。 類裝飾器應用于類構造函數,可以用來監視,修改或替換類定義。 傳入一個參數

      類裝飾器:普通裝飾器(無法傳參)

      function logClass(params:any){
      
          console.log(params);
          // params 就是當前類
          params.prototype.apiUrl='動態擴展的屬性';
          params.prototype.run=function(){
              console.log('我是一個run方法');
          }
      
      }
      
      @logClass
      class HttpClient{
          constructor(){
          }
          getData(){
      
          }
      }
      var http:any=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('http://www.itying.com/api')
      class HttpClient{
          constructor(){
          }
      
          getData(){
      
          }
      }
      
      var http:any=new HttpClient();
      console.log(http.apiUrl);
      

      類裝飾器案例

      下面是一個重載構造函數的例子。
      裝飾器表達式會在運行時當作函數被調用,類的構造函數作為其唯一的參數。
      如果類裝飾器返回一個值,它會使用提供的構造函數來替換類的聲明。

      function logClass(target:any){
          console.log(target);
          return class extends target{
              apiUrl:any='我是修改后的數據';
              getData(){
                  this.apiUrl=this.apiUrl+'----';
                  console.log(this.apiUrl);
              }
          }
      }
      
      
      @logClass
      class HttpClient{
          public apiUrl:string | undefined;
          constructor(){
              this.apiUrl='我是構造函數里面的apiUrl';
          }
          getData(){
              console.log(this.apiUrl);
          }
      }
      
      var http=new HttpClient();
      http.getData();
      

      屬性裝飾器

      屬性裝飾器表達式會在運行時當作函數被調用,傳入下列2個參數:

      1. 對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象。
      2. 成員的名字。

      類裝飾器

      function logClass(params:string){
          return function(target:any){
              // console.log(target);
              // console.log(params);       
              
          }
      }
      

      屬性裝飾器

      function logProperty(params:any){
          return function(target:any,attr:any){
              console.log(target);
              console.log(attr);
              target[attr]=params;
          }
      }
      @logClass('xxxx')
      class HttpClient{
          @logProperty('http://itying.com')
          public url:any |undefined;
          constructor(){
          }
          getData(){
              console.log(this.url);
          }
      }
      var http=new HttpClient();
      http.getData();
      

      方法裝飾器

      它會被應用到方法的 屬性描述符上,可以用來監視,修改或者替換方法定義。
      方法裝飾會在運行時傳入下列3個參數:
      2. 對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象。
      2. 成員的名字。
      3. 成員的屬性描述符。

      方法裝飾器一

      function get(params:any){
          return function(target:any,methodName:any,desc:any){
              console.log(target);
              console.log(methodName);
              console.log(desc);
              target.apiUrl='xxxx';
              target.run=function(){
                  console.log('run');
              }
          }
      }
      
      class HttpClient{  
          public url:any |undefined;
          constructor(){
          }
          @get('http://www.itying,com')
          getData(){
              console.log(this.url);
          }
      }
      
      var http:any=new HttpClient();
      console.log(http.apiUrl);
      http.run();
      

      方法裝飾器二

      function get(params:any){
          return function(target:any,methodName:any,desc:any){
              console.log(target);
              console.log(methodName);
              console.log(desc.value);       
              
              //修改裝飾器的方法  把裝飾器方法里面傳入的所有參數改為string類型
      
              //1、保存當前的方法
      
              var oMethod=desc.value;
              desc.value=function(...args:any[]){                
                  args=args.map((value)=>{
                      return String(value);
                  })
                  oMethod.apply(this,args);
              }
      
          }
      }
      
      class HttpClient{  
          public url:any |undefined;
          constructor(){
          }
          @get('http://www.itying,com')
          getData(...args:any[]){
              console.log(args);
              console.log('我是getData里面的方法');
          }
      }
      
      var http=new HttpClient();
      http.getData(123,'xxx');
      

      方法參數裝飾器

      參數裝飾器表達式會在運行時當作函數被調用,可以使用參數裝飾器為類的原型增加一些元素數據 ,傳入下列3個參數:

      1. 對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象。
      2. 方法的名字。
      3. 參數在函數參數列表中的索引。
      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('xxxxx') uuid:any){               
                      console.log(uuid);
                  }
       }
      
      
       var http:any = new HttpClient();
       http.getData(123456);
      console.log( http.apiUrl);
      

      裝飾器執行順序

      屬性》方法》方法參數》類
      如果有多個同樣的裝飾器,它會先執行后面的

      function logClass1(params:string){
          return function(target:any){
            console.log('類裝飾器1')
          }
      }
      
      function logClass2(params:string){
          return function(target:any){
            console.log('類裝飾器2')
          }
      }
      
      function logAttribute1(params?:string){
          return function(target:any,attrName:any){
            console.log('屬性裝飾器1')
          }
      }
      
      function logAttribute2(params?:string){
          return function(target:any,attrName:any){
            console.log('屬性裝飾器2')
          }
      }
      
      function logMethod1(params?:string){
          return function(target:any,attrName:any,desc:any){
            console.log('方法裝飾器1')
          }
      }
      function logMethod2(params?:string){
          return function(target:any,attrName:any,desc:any){
            console.log('方法裝飾器2')
          }
      }
      
      
      
      function logParams1(params?:string){
          return function(target:any,attrName:any,desc:any){
            console.log('方法參數裝飾器1')
          }
      }
      
      function logParams2(params?:string){
          return function(target:any,attrName:any,desc:any){
            console.log('方法參數裝飾器2')
          }
      }
      
      
      
      @logClass1('http://www.itying.com/api')
      @logClass2('xxxx')
      class HttpClient{
          @logAttribute1()
          @logAttribute2()
          public apiUrl:string | undefined;
          constructor(){
          }
      
          @logMethod1()
          @logMethod2()
          getData(){
              return true;
          }
      
          setData(@logParams1() attr1:any,@logParams2() attr2:any,){
      
          }
      }
      
      var http:any=new HttpClient();
      
      posted @ 2021-09-15 15:41  雅痞_yuppie  閱讀(549)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国内在线视频一区二区三区| 岛国最新亚洲伦理成人| 日韩人妻不卡一区二区三区| 富川| 四虎国产精品久久免费精品| 国产成熟女人性满足视频| 国产又色又爽又黄的在线观看 | 亚洲成人av在线资源| 亚洲国产欧美一区二区好看电影 | 成 人色 网 站 欧美大片| 午夜福利国产盗摄久久性| 18禁无遮挡啪啪无码网站| 黑人异族巨大巨大巨粗| 蜜臀久久99精品久久久久久| 国产av日韩精品一区二区| 麻豆亚洲精品一区二区| 亚洲欧洲日韩国内高清| 国产av仑乱内谢| 免费看无码自慰一区二区| 欧美成人精品高清在线播放| 午夜国人精品av免费看| 亚洲美女少妇偷拍萌白酱| 熟妇人妻无码中文字幕老熟妇| 国产国产午夜福利视频| 亚洲gv天堂无码男同在线观看 | 精品无码成人片一区二区98| 农村老熟女一区二区三区| 国产欧美日韩亚洲一区二区三区| a级黑人大硬长爽猛出猛进| 日韩国产欧美精品在线| 欧美 亚洲 日韩 在线综合| 亚洲精品天堂在线观看| 亚洲综合伊人久久综合| 视频免费完整版在线播放| 国产AV巨作丝袜秘书| 国产精品无码无在线观看| 亚洲熟女精品一区二区| 男女啪啪高潮激烈免费版| 国产色一区二区三区四区| 清涧县| 亚洲精品漫画一二三区|