【问题标题】:Why do decorators have to apply(this) to a function为什么装饰器必须将(this)应用于函数
【发布时间】:2019-11-16 07:39:09
【问题描述】:

我在 javascript 上下文中阅读了很多关于此的内容,并试图理解装饰器代码。每当我查看如下装饰器代码时,它总是将此输入函数应用于“this”,即使输入函数没有对“this”进行任何引用。这是为什么?是否有必要总是在装饰器中将函数应用于“this”?它还在很多地方说装饰器不能是箭头函数,因为绑定到 this。有人可以为什么这会影响功能吗?

function doSomething(name) {
  console.log('Hello, ' + name);
}

function loggingDecorator(wrapped) {
  return function() {
    console.log('Starting');
    const result = wrapped.apply(this, arguments);
    console.log('Finished');
    return result;
  }
}

const wrapped = loggingDecorator(doSomething);

【问题讨论】:

  • "即使输入函数没有对 'this' 进行任何引用" - 但如果这样做了呢?关键是装饰者无法知道,所以它总是要安全行事。

标签: javascript typescript this decorator


【解决方案1】:

当被包装的函数作为某个对象的方法被调用时,这是为包装函数提供正确的this 所必需的,请考虑:

function loggingDecorator(wrapped) {
    return function () {
        console.log('Starting');

        //const result = wrapped() // <-- this doesn't work
        const result = wrapped.apply(this, arguments); // <-- this does

        console.log('Finished');
        return result;
    }
}

class T {
    constructor() {
        this.property = 42;
    }

    someMethod() {
        console.log(this.property)
    }
}


T.prototype.someMethod = loggingDecorator(T.prototype.someMethod);

t = new T;
t.someMethod();

这里,我们的装饰函数调用this等于t,并且必须将这个this传递给原始方法,否则它将无法解析this.property。显然,如果原始函数不以任何方式使用this,则没有必要这样做,但始终使用apply 编写装饰器是一个好习惯,这样它们就可以在任何上下文中使用。

【讨论】:

  • 谢谢,我明白了。我只是好奇为什么在所有示例中都没有提到this,但我想这只是一个好习惯
  • @VikramKhemlani:是的,但请注意,在 TS 中实现的实际装饰器('@' 语法)甚至不能与独立函数一起使用,这使得 apply 是强制性的。
猜你喜欢
  • 2018-01-16
  • 2021-11-29
  • 2015-02-01
  • 1970-01-01
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
  • 2015-08-14
相关资源
最近更新 更多