0

I am learning typescript on Udemy and the instructor is going through the method decorator to try to bind a method to the instance when it invoked in a event listener.

The way he did is to use decorator in TypeScript and amend the Property Descriptor.

Code is shown below.

function Autobind(_: any, _2: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    console.log(descriptor)
    console.log(originalMethod)
    const adjDescriptor: PropertyDescriptor = {
        configurable: true,
        enumerable: false,
        get() {
            const boundFn = originalMethod.bind(this);
            return boundFn;
        }
    }
    console.log(adjDescriptor)
    return adjDescriptor;
}

class Printer {
    message = 'This works!';

    @Autobind
    showMessage() {
        console.log(this.message);
    }
}

const p = new Printer();

const button = document.querySelector('button')!;
button.addEventListener('click', p.showMessage);

I have two questions on his method.

  1. How the 'get' method of the property descriptor get invoked in this case?
  2. Originally the descriptor has a value property which is the showMessage method. I am curious why he did not amend the value property. Instead, he is adding the get method to the descriptor and ignore the value property.
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
lunaayase
  • 45
  • 8
  • The `get` method of the descriptor becomes the **getter** for the `.showMessage` property, which is now an accessor property not a data property. The original `value` is not ignored, it is used as `originalMethod` in the getter, to return a bound function when you access the property. – Bergi Dec 05 '22 at 01:46
  • 1
    Do you know how to create a getter using [`Object.defineProperty`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)? – Bergi Dec 05 '22 at 01:47
  • Sorry that I am new to this. I have read the MDN document, and it seems that we there are methods to define the properties of the properties descriptor but I am not sure exactly how they works. – lunaayase Dec 05 '22 at 01:50
  • I am not sure why he returns the new one that only contains get method but without the value but it seems that it is the constraint of using the get method. Besides, I have one more questions that how the function showMessage got invoked? I can only think of when the class is defined, the decorator do sth to overwrite the property descriptor. But then, the get method returns a function, but how that function is being invoked? – lunaayase Dec 05 '22 at 01:54
  • "*it seems that it is the constraint of using the get method*" - yes, you cannot have a descriptor with both a `value` and a `get` - the object wouldn't know what to do when you access the property. "*how the function showMessage got invoked?*" - it is invoked when the even is fired. You can also do `const show = p.showMessage; show()` to a similar effect. See also [this question](https://stackoverflow.com/q/20279484/1048572) for why the whole endeavour is necessary. – Bergi Dec 05 '22 at 01:58
  • Thanks for your replies OTZ. So, is it meaning that when we call a method (e.g. A) of an object, either value of A (i.e. function definition) is returned/ get method of A is being invoked? – lunaayase Dec 05 '22 at 02:02
  • No. If it's a getter, first the getter is invoked, then the returned function is invoked. Try placing another log statement in the getter, try returning something that is not a function, see what happens. – Bergi Dec 05 '22 at 06:21

0 Answers0