Vikram Khemlani
Vikram Khemlani

Reputation: 635

Why do decorators have to apply(this) to a function

I've been reading a lot about this in javascript context and been trying to understanding decorator code. Whenever I look at decorator code, such as below, it always applies this input function to 'this' even though the input function does not make any references to 'this'. Why is that? Is it necessary to apply a function to 'this' in a decorator always? It also says in many places that the decorator cannot be an arrow function because of the binding to this. Can someone why that would affect the function?

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);

Upvotes: 0

Views: 66

Answers (1)

georg
georg

Reputation: 214959

This is necessary to give the wrapped function a correct this when it's called as a method of some object, consider:

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();

Here, our decorated function is called with this equal to t and have to pass this this down to the original method, otherwise it won't be able to resolve this.property. Obviously, if the original function doesn't use this in any way, this is not necessary, still, it's a good practice to always write decorators with apply, so that they can be used in any context.

Upvotes: 2

Related Questions