如何在方法装饰器中管理 "this" 绑定?

How to manage "this" binding in method decorator?

我一直在尝试在装饰方法中使用 this 但没有成功。我看到编译器是如何翻译这个的,实际上它没有使用正确的 this,而是在 时分配的一个名为 _this 的变量this 没有绑定任何东西。

我尝试将 descriptor.value 绑定到目标,但没有成功

这是我的代码:

export function PathMethod<T>(path: string): Function {
    return (target: ServicioRest<T>, propertyKey: string, descriptor: PropertyDescriptor): void => {
        const original: Function = descriptor.value;
        descriptor.value = (entity: T): T => {
            const initialPath: string = this.path;
            if (!this.path.endsWith('/')) {
                this.path += '/';
            }
            this.path += path;
            const result: T = original(entity);
            this.path = initialPath;
            return result;
        };
    };
}

翻译如下:

function PathMethod(path) {
    var _this = this;
    return function (target, propertyKey, descriptor) {
        /** @type {?} */
        var original = descriptor.value;
        descriptor.value = function (entity) {
            /** @type {?} */
            var initialPath = _this.path;
            if (!_this.path.endsWith('/')) {
                _this.path += '/';
            }
            _this.path += path;
            /** @type {?} */
            var result = original(entity);
            _this.path = initialPath;
            return result;
        };
    };
}

但实际上翻译应该是这样的:

function PathMethod(path) {
    return function (target, propertyKey, descriptor) {
        /** @type {?} */
        var original = descriptor.value;
        descriptor.value = function (entity) {
            /** @type {?} */
            var initialPath = this.path;
            if (!this.path.endsWith('/')) {
                this.path += '/';
            }
            this.path += path;
            /** @type {?} */
            var result = original(entity);
            this.path = initialPath;
            return result;
        };
    };
}

有人知道如何管理该解决方案吗?我的代码有什么问题吗?

如果您不想从声明上下文中捕获 this,请使用常规函数而不是箭头函数。 _this ts 插入是为了模拟 es2015 箭头函数的行为。常规 function 表达式和声明不会这样做。虽然 => 较短,但在处理两个 see docs 之间时,您应该始终考虑 this 行为。

export function PathMethod<T>(path: string): Function {
    return (target: ServicioRest<T>, propertyKey: string, descriptor: PropertyDescriptor): void => {
        const original: Function = descriptor.value;
        descriptor.value = function (entity: T): T {
            const initialPath: string = this.path;
            if (!this.path.endsWith('/')) {
                this.path += '/';
            }
            this.path += path;
            const result: T = original(entity);
            this.path = initialPath;
            return result;
        };
    };
}