国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

TypeScript 自定義裝飾器

這篇具有很好參考價值的文章主要介紹了TypeScript 自定義裝飾器。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

(預測未來最好的方法就是把它創(chuàng)造出來——尼葛洛龐帝)

TypeScript 自定義裝飾器

裝飾器

裝飾器一種更現(xiàn)代的代碼模式,通過使用@的形式注入在屬性,寄存器,方法,方法參數(shù)和類中,比如在Angular,Nestjs和midway等流行框架中也都用到了裝飾器。
官方說明
對裝飾器更詳細的相關(guān)說明

tc39提案

tc39提案一共分為五個階段

Stage 0 - 設(shè)想(Strawman):只是一個想法,可能有 Babel插件。
Stage 1 - 建議(Proposal):這是值得跟進的。
Stage 2 - 草案(Draft):初始規(guī)范。
Stage 3 - 候選(Candidate):完成規(guī)范并在瀏覽器上初步實現(xiàn)。
Stage 4 - 完成(Finished):將添加到下一個年度版本發(fā)布中。

裝飾器目前已經(jīng)在階段3,相信不久的將來,js中也會支持裝飾器。在typescript5.0中已經(jīng)完全支持了裝飾器。
該提案進度更詳細的相關(guān)說明

裝飾器實踐

tsconfig.json

{
  "compilerOptions": {
    "target": "ES6", // 為發(fā)出的JavaScript設(shè)置JavaScript語言版本,并包含兼容的庫聲明
    "experimentalDecorators": true, // 啟用對遺留實驗裝飾器的實驗支持
    "module": "ES6", // 指定生成的模塊代碼
    "esModuleInterop": true, // 發(fā)出額外的JavaScript以簡化對導入CommonJS模塊的支持。這為類型兼容性啟用了“allowSyntheticDefaultImports”
    "moduleResolution": "node", // 指定TypeScript如何從給定的模塊說明符中查找文件
    "outDir": "dist", // 為所有發(fā)出的文件指定輸出文件夾
    "rootDir": "src", // 指定源文件中的根文件夾
  },
  "include": [ // 需要編譯的目錄文件
    "src/**/*",
  ],
  "exclude": [ // 需要排除的目錄文件
    "node_modules"
  ]
}

官方更詳細的配置說明

類裝飾器

typescript

// 通過裝飾器對類進行擴展,減少對代碼侵入性和業(yè)務(wù)間的耦合性
// constructor參數(shù)為類的構(gòu)造函數(shù)
const classExtends = () => {
  const ClassDecorator = (constructor: Function) => {
    console.log('ClassDecorator---');
    // 擴展類屬性
    constructor.prototype.name = 'ClassDecoratorName';
    // 擴展類方法
    constructor.prototype.run = () => {
      console.log('ClassDecorator run test');
    }
  };
  interface Test {
    name: string;
    run (): void;
  }

  @ClassDecorator
  class Test {
  }
  new Test().run();
  const obj = { name: 'adsa' };
  Reflect.get(obj, 'name');
};
classExtends();

// 通過裝飾器入?yún)⒌男问綄︻愡M行擴展,使用參數(shù)可以對業(yè)務(wù)進行更強的定制化處理
const classExtendByParams = () => {
  const ClassDecorator = (param: string) => {
    return function (constructor: Function) {
      // 針對入?yún)⒆霾煌奶幚?/span>
      constructor.prototype.run = () => {
        if (param === 'agent') {
          console.log('classExtendByParams run agent');
        } else if (param === 'user') {
          console.log('classExtendByParams run user');
        }
      };
    }
  };
  interface Test {
    name: string;
    run (): void;
  }
  @ClassDecorator('agent')
  class Test {
  }
  new Test().run();
};
classExtendByParams();

// 通過裝飾器工廠方法進行擴展,工廠方法裝飾器可以和類型更好的兼容
const classExtendOfFactory = () => {
  const ClassDecorator = (param: string) => {
    return function <T extends new (...args: any[]) => any> (constructor: T) {
      return class extends constructor {
        run () {
          if (param === 'agent') {
            console.log('classExtendOfFactory run agent');
          } else if (param === 'user') {
            console.log('classExtendOfFactory run user');
          }
        };
      }
    }
  };
  const Test = ClassDecorator('user')(
    class { }
  );
  new Test().run();
};
classExtendOfFactory();

javascript

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// 通過裝飾器對類進行擴展,減少對代碼侵入性和業(yè)務(wù)間的耦合性
// constructor參數(shù)為類的構(gòu)造函數(shù)
const classExtends = () => {
    const ClassDecorator = (constructor) => {
        console.log('ClassDecorator---');
        // 擴展類屬性
        constructor.prototype.name = 'ClassDecoratorName';
        // 擴展類方法
        constructor.prototype.run = () => {
            console.log('ClassDecorator run test');
        };
    };
    let Test = class Test {
    };
    Test = __decorate([
        ClassDecorator
    ], Test);
    new Test().run();
    const obj = { name: 'adsa' };
    Reflect.get(obj, 'name');
};
classExtends();
// 通過裝飾器入?yún)⒌男问綄︻愡M行擴展,使用參數(shù)可以對業(yè)務(wù)進行更強的定制化處理
const classExtendByParams = () => {
    const ClassDecorator = (param) => {
        return function (constructor) {
            // 針對入?yún)⒆霾煌奶幚?/span>
            constructor.prototype.run = () => {
                if (param === 'agent') {
                    console.log('classExtendByParams run agent');
                }
                else if (param === 'user') {
                    console.log('classExtendByParams run user');
                }
            };
        };
    };
    let Test = class Test {
    };
    Test = __decorate([
        ClassDecorator('agent')
    ], Test);
    new Test().run();
};
classExtendByParams();
// 通過裝飾器工廠方法進行擴展,工廠方法裝飾器可以和類型更好的兼容
const classExtendOfFactory = () => {
    const ClassDecorator = (param) => {
        return function (constructor) {
            return class extends constructor {
                run() {
                    if (param === 'agent') {
                        console.log('classExtendOfFactory run agent');
                    }
                    else if (param === 'user') {
                        console.log('classExtendOfFactory run user');
                    }
                }
                ;
            };
        };
    };
    const Test = ClassDecorator('user')(class {
    });
    new Test().run();
};
classExtendOfFactory();

方法裝飾器

typescript

/**
 * 入?yún)⒔忉? * target: 對于靜態(tài)成員來說是類的構(gòu)造函數(shù),對于實例成員來說是類的原型對象
 * propertyKey: 屬性的名稱
 * descriptor: 屬性的描述器
 */
/**
 * PropertyDescriptor參數(shù)解釋
 * PropertyDescriptor的參數(shù)各項為js的屬性描述符,在創(chuàng)建變量或方法等對象時,js會默認賦予這些描述符
 * 詳細的閱讀https://www.tektutorialshub.com/javascript/javascript-property-descriptors-enumerable-writable-configurable/
 * descriptor 參數(shù)
 * value 方法自身
 * writable 該方法是否可以被變更
 * enumerable 是否可以被枚舉
 * configurable 決定是否可配置,如果為false,則value,writable,enumerable不能被修改
 */

// 通過裝飾器對方法進行擴展,減少對代碼侵入性和業(yè)務(wù)間的耦合性
const methodExtends = () => {
  const MethodDecorator = (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
    // 獲取方法本身
    const method = descriptor.value;
    // 對該方法的生命周期進行操作
    descriptor.value = (...args) => {
      console.log('MethodDecorator before run');
      const data = method.call(this, args);
      console.log('MethodDecorator after run');
      return data;
    };
  };
  class Test {

    @MethodDecorator
    method () {
      return ';;;;';
    }

  }
  console.log(new Test().method());
};
methodExtends();

// 通過裝飾入?yún)⒌男问綄Ψ椒ㄟM行擴展,使用參數(shù)可以對業(yè)務(wù)進行更強的定制化處理
const methodExtendsByParams = () => {
  const MethodDecorator = (param: string) => {
    console.log('methodExtendsByParams', param);
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
      // 獲取方法本身
      const method = descriptor.value;
      // 對該方法的生命周期進行操作
      descriptor.value = (...args) => {
        console.log('before run');
        const data = method.call(this, args);
        console.log('after run');
        return data;
      };
    }
  };
  class Test {

    @MethodDecorator('user')
    method () {
      return ';;;;';
    }

  }
  console.log(new Test().method());
};
methodExtendsByParams();

javascript

/**
 * 入?yún)⒔忉? * target: 對于靜態(tài)成員來說是類的構(gòu)造函數(shù),對于實例成員來說是類的原型對象
 * propertyKey: 屬性的名稱
 * descriptor: 屬性的描述器
 */
/**
 * PropertyDescriptor參數(shù)解釋
 * PropertyDescriptor的參數(shù)各項為js的屬性描述符,在創(chuàng)建變量或方法等對象時,js會默認賦予這些描述符
 * 詳細的閱讀https://www.tektutorialshub.com/javascript/javascript-property-descriptors-enumerable-writable-configurable/
 * descriptor 參數(shù)
 * value 方法自身
 * writable 該方法是否可以被變更
 * enumerable 是否可以被枚舉
 * configurable 決定是否可配置,如果為false,則value,writable,enumerable不能被修改
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// 通過裝飾器對方法進行擴展,減少對代碼侵入性和業(yè)務(wù)間的耦合性
const methodExtends = () => {
    const MethodDecorator = (target, propertyKey, descriptor) => {
        // 獲取方法本身
        const method = descriptor.value;
        // 對該方法的生命周期進行操作
        descriptor.value = (...args) => {
            console.log('MethodDecorator before run');
            const data = method.call(this, args);
            console.log('MethodDecorator after run');
            return data;
        };
    };
    class Test {
        method() {
            return ';;;;';
        }
    }
    __decorate([
        MethodDecorator
    ], Test.prototype, "method", null);
    console.log(new Test().method());
};
methodExtends();
// 通過裝飾入?yún)⒌男问綄Ψ椒ㄟM行擴展,使用參數(shù)可以對業(yè)務(wù)進行更強的定制化處理
const methodExtendsByParams = () => {
    const MethodDecorator = (param) => {
        console.log('methodExtendsByParams', param);
        return (target, propertyKey, descriptor) => {
            // 獲取方法本身
            const method = descriptor.value;
            // 對該方法的生命周期進行操作
            descriptor.value = (...args) => {
                console.log('before run');
                const data = method.call(this, args);
                console.log('after run');
                return data;
            };
        };
    };
    class Test {
        method() {
            return ';;;;';
        }
    }
    __decorate([
        MethodDecorator('user')
    ], Test.prototype, "method", null);
    console.log(new Test().method());
};
methodExtendsByParams();

方法參數(shù)裝飾器

typescript

// 通過裝飾器對方法中的屬性進行擴展
/**
 * target 實例自身
 * methodName 方法名
 * paramIndex 參數(shù)的下標位置
 */
const methodParamExtends = () => {
  const methodPramDecorator = (param: string) => {
    return (target: any, methodName: string, paramIndex: any) => {
      console.log('target', target, methodName, paramIndex);
      target.decoratorData = '222';
    }
  };
  class Test {
    decoratorData!: string;
    init (@methodPramDecorator('agent') type: string) {
      return type;
    }
  }
  const test = new Test();
  const data = test.init('20230611');
  console.log(data, test.decoratorData);
  return data;
};
methodParamExtends();

javascript

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
// 通過裝飾器對方法中的屬性進行擴展
/**
 * target 實例自身
 * methodName 方法名
 * paramIndex 參數(shù)的下標位置
 */
const methodParamExtends = () => {
    const methodPramDecorator = (param) => {
        return (target, methodName, paramIndex) => {
            console.log('target', target, methodName, paramIndex);
            target.decoratorData = '222';
        };
    };
    class Test {
        init(type) {
            return type;
        }
    }
    __decorate([
        __param(0, methodPramDecorator('agent'))
    ], Test.prototype, "init", null);
    const test = new Test();
    const data = test.init('20230611');
    console.log(data, test.decoratorData);
    return data;
};
methodParamExtends();

寄存器裝飾器

typescript

// 通過裝飾器對寄存器進行擴展
/**
 * target 實例自身
 * propertyKey 屬性key
 * descriptor 屬性描述符
 */
const setgetExtends = () => {
  const SetGetDecorator = (param: string) => {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
      const set = descriptor.set;
      const get = descriptor.get;
      descriptor.set = function (value) {
        console.log('GetDecorator before run', value);
        if (typeof value === 'string') {
          value += ` set decrator ${param}`;
        }
        set.call(this, value);
        console.log('GetDecorator after run', value);
      };
      descriptor.get = function () {
        console.log('GetDecorator before run', target);
        let data = get.call(this);
        console.log('GetDecorator after run');
        if (typeof data === 'string') {
          data += ` get decrator ${param}`;
        }
        return data;
      }
    }
  };

  class Test {

    #name: string;

    @SetGetDecorator('custom setget')
    set name (name: string) {
      this.#name = name;
    }
    get name () {
      return this.#name;
    }

  }
  const user = new Test();
  user.name = 'user';
  console.log('setgetExtends', user.name);
};
setgetExtends();

javascript

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to set private field on non-instance");
    }
    privateMap.set(receiver, value);
    return value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};
// 通過裝飾器對寄存器進行擴展
/**
 * target 實例自身
 * propertyKey 屬性key
 * descriptor 屬性描述符
 */
const setgetExtends = () => {
    var _name;
    const SetGetDecorator = (param) => {
        return (target, propertyKey, descriptor) => {
            const set = descriptor.set;
            const get = descriptor.get;
            descriptor.set = function (value) {
                console.log('GetDecorator before run', value);
                if (typeof value === 'string') {
                    value += ` set decrator ${param}`;
                }
                set.call(this, value);
                console.log('GetDecorator after run', value);
            };
            descriptor.get = function () {
                console.log('GetDecorator before run', target);
                let data = get.call(this);
                console.log('GetDecorator after run');
                if (typeof data === 'string') {
                    data += ` get decrator ${param}`;
                }
                return data;
            };
        };
    };
    class Test {
        constructor() {
            _name.set(this, void 0);
        }
        set name(name) {
            __classPrivateFieldSet(this, _name, name);
        }
        get name() {
            return __classPrivateFieldGet(this, _name);
        }
    }
    _name = new WeakMap();
    __decorate([
        SetGetDecorator('custom setget')
    ], Test.prototype, "name", null);
    const user = new Test();
    user.name = 'user';
    console.log('setgetExtends', user.name);
};
setgetExtends();

屬性裝飾器

typescript

// 通過屬性裝飾器對屬性進行擴展
const paramExtends = () => {
  const ParamDecorator = (param: string) => {
    return function (target: any, key: any) {
      target[key] = param;
      console.log(`init param ${key} to ${param}`);
    }
  }
  class Test {
    @ParamDecorator('www.baidu.com')
    private url!: string;
    getName () {
      return this.url;
    }
  }
  const test = new Test();
  const data = test.getName();
  console.log('data', data);
};
paramExtends();

javascript

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// 通過屬性裝飾器對屬性進行擴展
const paramExtends = () => {
    const ParamDecorator = (param) => {
        return function (target, key) {
            target[key] = param;
            console.log(`init param ${key} to ${param}`);
        };
    };
    class Test {
        getName() {
            return this.url;
        }
    }
    __decorate([
        ParamDecorator('www.baidu.com')
    ], Test.prototype, "url", void 0);
    const test = new Test();
    const data = test.getName();
    console.log('data', data);
};
paramExtends();

裝飾器執(zhí)行順序

示例代碼

typescript

// 不同裝飾器的執(zhí)行順序

const CustomClassDecorator = (constructor: Function) => {
  console.log('類裝飾器');
};
const CustomMethodDecorator = (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
  console.log('方法裝飾器');
};
const CustomMethodParamDecorator = (target: any, methodName: string, paramIndex: any) => {
  console.log('方法參數(shù)裝飾器');
}
const CustomParamDecorator = (target: any, key: any) => {
  console.log(`參數(shù)裝飾器`);
}
const CustomSetGetDecorator = (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
  console.log('寄存器裝飾器');
}

@CustomClassDecorator
class Test {

  @CustomParamDecorator
  sex!: string;

  #name !: string;

  @CustomSetGetDecorator
  set name (name: string) {
    this.#name = name;
  }
  get name () {
    return this.#name
  }

  @CustomMethodDecorator
  handleName (@CustomMethodParamDecorator prefix: string) {
    return prefix + this.name;
  }

}
const instance = new Test();
const data = instance.handleName('prefix');
console.log(data);

javascript

// 不同裝飾器的執(zhí)行順序
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to set private field on non-instance");
    }
    privateMap.set(receiver, value);
    return value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};
var _name;
const CustomClassDecorator = (constructor) => {
    console.log('類裝飾器');
};
const CustomMethodDecorator = (target, propertyKey, descriptor) => {
    console.log('方法裝飾器');
};
const CustomMethodParamDecorator = (target, methodName, paramIndex) => {
    console.log('方法參數(shù)裝飾器');
};
const CustomParamDecorator = (target, key) => {
    console.log(`參數(shù)裝飾器`);
};
const CustomSetGetDecorator = (target, propertyKey, descriptor) => {
    console.log('寄存器裝飾器');
};
let Test = class Test {
    constructor() {
        _name.set(this, void 0);
    }
    set name(name) {
        __classPrivateFieldSet(this, _name, name);
    }
    get name() {
        return __classPrivateFieldGet(this, _name);
    }
    handleName(prefix) {
        return prefix + this.name;
    }
};
_name = new WeakMap();
__decorate([
    CustomParamDecorator
], Test.prototype, "sex", void 0);
__decorate([
    CustomSetGetDecorator
], Test.prototype, "name", null);
__decorate([
    CustomMethodDecorator,
    __param(0, CustomMethodParamDecorator)
], Test.prototype, "handleName", null);
Test = __decorate([
    CustomClassDecorator
], Test);
const instance = new Test();
const data = instance.handleName('prefix');
console.log(data);

執(zhí)行結(jié)果

參數(shù)裝飾器
寄存器裝飾器
方法參數(shù)裝飾器
方法裝飾器
類裝飾器
prefixundefined

裝飾器原理

以下代碼是重寫過的,方便理解和回顧。由于Reflect.decorate裝飾器反射機制還不支持,且相關(guān)資料較少,所以在本文中不進行深入研究。文章來源地址http://www.zghlxwxcb.cn/news/detail-483850.html

/**
 * Test = __decorate([ClassDecrator], Test)
 * decorators 裝飾器列表
 * target 類實例
 * key 屬性名稱
 * desc 變量屬性描述符
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  /**
   * 獲取請求參數(shù),咱本示例中,請求參數(shù)為2
   * Test = __decorate([ClassDecrator], Test)
   */
  var c = arguments.length
  // 初始化r變量
  var r = null;
  // 如果請求參數(shù)小于三個,在本示例中滿足
  if (c < 3) {
    // 將類實例賦予r,也就是將Test賦給r
    r = target;
  } else {
    // 如果屬性描述符為空
    if (desc === null) {
      // 返回指定屬性名的描述符
      desc = Object.getOwnPropertyDescriptor(target, key);
      r = desc;
    } else {
      // 如果存在描述符,則直接賦予r
      r = desc;
    }
  }
  // 由此可見,在類裝飾器下,r為類實例本身,在方法等裝飾器下,r為屬性描述符

  var d;
  // 是否支持es6的Reflect,暫時跳過,文章后面單獨會將
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
    r = Reflect.decorate(decorators, target, key, desc)
  }
  // 如果不支持es6的Reflect,則向下執(zhí)行
  else {
    // 在這里倒敘循環(huán)執(zhí)行每一個裝飾器,由此看出ts裝飾器的執(zhí)行順序
    for (var i = decorators.length - 1; i >= 0; i--) {
      d = decorators[i];
      if (d) {
        var temp = null;
        if (c < 3) {
          temp = d(r);
        } else {
          if (c > 3) {
            temp = d(target, key, r);
          } else {
            temp = d(target, key);
          }
        }
        if (temp) {
          r = temp;
        }
      }
    }
  }
  // 如果參數(shù)大于3個,則將屬性名和屬性描述符賦予該實例
  if (c > 3 && r) {
    Object.defineProperty(target, key, r);
  }
  // 返回該實例實例或?qū)傩悦枋龇?/span>
  return r;
};

到了這里,關(guān)于TypeScript 自定義裝飾器的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【TypeScript】TS進階-裝飾器(九)

    ??個人主頁: 不叫貓先生 ???♂?作者簡介:前端領(lǐng)域新星創(chuàng)作者、阿里云專家博主,專注于前端各領(lǐng)域技術(shù),共同學習共同進步,一起加油呀! ??系列專欄:vue3從入門到精通、TypeScript從入門到實踐 ??資料領(lǐng)取:前端進階資料以及文中源碼可以找我免費領(lǐng)取 ??社群招

    2024年02月21日
    瀏覽(18)
  • 面試題-TS(八):什么是裝飾器(decorators)?如何在 TypeScript 中使用它們?

    面試題-TS(八):什么是裝飾器(decorators)?如何在 TypeScript 中使用它們? 在TypeScript中,裝飾器( Decorators )是一種用于增強代碼功能的特殊類型聲明。裝飾器提供了一種在類、方法、屬性等代碼元素上注釋或修改的方式,使得我們可以通過裝飾器來擴展、修改或監(jiān)視代碼的

    2024年02月15日
    瀏覽(20)
  • 微信小程序onLoad加載定義好的函數(shù)

    微信小程序onLoad加載定義好的函數(shù)

    運行時老報錯 后來修改為正確的代碼 再嘗試運行,一切OK!

    2024年04月12日
    瀏覽(36)
  • 《精英的傲慢:好的社會該如何定義成功》筆記與摘錄

    《精英的傲慢:好的社會該如何定義成功》筆記與摘錄

    目錄 作者簡介 書內(nèi)容簡介 經(jīng)典摘錄 1、現(xiàn)狀與現(xiàn)象 2、什么是優(yōu)績至上原則 3、對優(yōu)績至上原則贊同與否的討論 4、 優(yōu)績至上原則存在的爭議點 5、?作為哲學家,桑德爾從道德哲學角度的思考 6、作者對優(yōu)績制的批判 7、流動性與平等的關(guān)系 8、我們該如何擺脫優(yōu)績主義的陷阱

    2024年02月03日
    瀏覽(16)
  • 《精英的傲慢:好的社會該如何定義成功》筆記與摘錄二

    《精英的傲慢:好的社會該如何定義成功》筆記與摘錄二

    目錄 ?編輯 筆記與摘錄 1、階層躍升的話語 2、優(yōu)績至上理念的核心 3、優(yōu)績?yōu)槭裁粗匾?4、不平等是制度的失敗,還是你的失敗? 5、一種思考什么樣的社會是公正的社會的方法 6、賺很多錢意味著什么 7、當市場價值被看作社會貢獻的代表后 8、當市場價值被看作稀缺程度的

    2024年02月04日
    瀏覽(16)
  • 時序預測 | MATLAB實現(xiàn)ELM極限學習機時間序列預測未來

    時序預測 | MATLAB實現(xiàn)ELM極限學習機時間序列預測未來

    預測效果 基本介紹 1.MATLAB實現(xiàn)ELM極限學習機時間序列預測未來; 2.運行環(huán)境Matlab2018及以上,data為數(shù)據(jù)集,單變量時間序列預測,運行主程序ELMTSF即可,其余為函數(shù)文件,無需運行; 3.遞歸預測未來數(shù)據(jù),可以控制預測未來大小的數(shù)目,適合循環(huán)性、周期性數(shù)據(jù)預測; 4.命令

    2024年02月09日
    瀏覽(18)
  • 智慧水務(wù)未來技術(shù)發(fā)展方向預測探討

    智慧水務(wù)未來技術(shù)發(fā)展方向預測探討

    隨著科技的不斷發(fā)展和城市化的加速,智慧水務(wù)作為一種新的水務(wù)模式,逐漸受到廣泛關(guān)注。未來,智慧水務(wù)將會面臨更多的技術(shù)挑戰(zhàn)和商機。本博客將對智慧水務(wù)的未來技術(shù)發(fā)展方向進行預測,以探討智慧水務(wù)未來可能的技術(shù)重點。 未來,人工智能技術(shù)將成為智慧水務(wù)領(lǐng)域

    2024年01月24日
    瀏覽(21)
  • 算法備案法規(guī)變遷:未來的預測和影響

    隨著科技的迅速發(fā)展和深度學習技術(shù)的普及,算法已經(jīng)成為企業(yè)的核心競爭力之一。從個性化推薦到自動駕駛,算法無處不在,極大地改變了我們的生活。然而,算法的“黑箱”特性也引起了廣泛的關(guān)注和討論,如何對算法進行有效的管理和監(jiān)控,成為了一個重要的問題。近

    2024年02月14日
    瀏覽(15)
  • 時序預測 | MATLAB實現(xiàn)基于RF隨機森林的時間序列預測-遞歸預測未來(多指標評價)

    時序預測 | MATLAB實現(xiàn)基于RF隨機森林的時間序列預測-遞歸預測未來(多指標評價)

    預測結(jié)果 基本介紹 MATLAB實現(xiàn)基于RF隨機森林的時間序列預測-遞歸預測未來(多指標評價) 1.MATLAB實現(xiàn)基于RF隨機森林的時間序列預測-遞歸預測未來(多指標評價); 2.運行環(huán)境Matlab2018及以上,data為數(shù)據(jù)集,單變量時間序列預測; 3.遞歸預測未來數(shù)據(jù),可以控制預測未來大小的數(shù)

    2024年02月12日
    瀏覽(30)
  • 【中秋國慶不斷更】OpenHarmony定義可動畫屬性:@AnimatableExtend裝飾器

    【中秋國慶不斷更】OpenHarmony定義可動畫屬性:@AnimatableExtend裝飾器

    @AnimatableExtend裝飾器用于自定義可動畫的屬性方法,在這個屬性方法中修改組件不可動畫的屬性。在動畫執(zhí)行過程時,通過逐幀回調(diào)函數(shù)修改不可動畫屬性值,讓不可動畫屬性也能實現(xiàn)動畫效果。 ? ● 可動畫屬性:如果一個屬性方法在animation屬性前調(diào)用,改變這個屬性的值

    2024年02月08日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包