【问题标题】:Change arguments of a function using a MethodDecorator, without altering the "this value"?使用 MethodDecorator 更改函数的参数,而不更改“此值”?
【发布时间】:2019-02-05 22:08:48
【问题描述】:

假设您必须在运行时使用装饰器更改方法参数。一个简单的简单示例:所有参数都设置为“Hello World”:

export const SillyArguments = (): MethodDecorator => {
  return (
      target: Object,
      propertyKey: string | symbol,
      descriptor: PropertyDescriptor
  ) => {
    const originalMethod = descriptor.value;
    descriptor.value = (...args: any[]) => {
      Object.keys(args).forEach(i => {
        args[i] = 'Hello World';
      });

      return originalMethod.apply(null, args);
    };

    return descriptor;
  }
};

示例用法:

class TestClass {
  private qux = 'qux';

  @SillyArguments()
  foo(val: any) {
    console.log(val);
    console.log(this.qux);
    this.bar();
  }

  bar() {
    console.log('bar');
  }
}

const test = new TestClass();
test.foo('Ciao mondo'); // prints "Hello World"

TypeError: 无法读取属性 'qux' of null

这里的问题是apply(null, args),它改变了this的上下文。这使得无法从 foo() 内部调用名为 qux 的实例变量。

另一种可能是将调用改为originalMethod.apply(target, args),但是这次quxundefined,而bar()可以调用。

是否有可能在 this 的上下文正确设置为实例的情况下调用 originalMethod

【问题讨论】:

    标签: javascript typescript ecmascript-6 typescript-decorator


    【解决方案1】:

    使用function 函数而不是箭头函数,以便您接收原始this 上下文并可以将其传递:

    export const SillyArguments = (): MethodDecorator => {
      return (
          target: Object,
          propertyKey: string | symbol,
          descriptor: PropertyDescriptor
      ) => {
        const originalMethod = descriptor.value;
        descriptor.value = function (...args: any[]) {
          Object.keys(args).forEach(i => {
            args[i] = 'Hello World';
          });
    
          return originalMethod.apply(this, args);
        };
    
        return descriptor;
      }
    };
    

    【讨论】:

    • 太棒了。谢谢。
    猜你喜欢
    • 2023-03-14
    • 2019-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 2014-03-15
    • 2012-02-23
    相关资源
    最近更新 更多